/**
 * Created by chenzp on 18-4-2.
 */
var Ptyxele = null;
/**
 * 核心主函数入口
 * Created by chenzp on 18-1-30.
 *
 */
+function () {

    var ptyxeleStoreData = new Object()

    var dictStoreData = new Object()

    Ptyxele = function () {
        var $sets = $('ptyxele-set')

        if ($sets.length == 0) return

        if ($sets.length > 0 && ptyxeleStoreData.isParse) return

        for (var i = 0; i < $sets.length; i++) {
            var $set = $sets.eq(i)
            var jsstr = $set.text().replace(/^\s*|\s*$/g, "")

            if (!jsstr) continue

            eval(jsstr)
        }


        //所有select框事件的处理
        $(document).on('click', function (e) {

            var parent = '.layui-unselect.layui-form-select'
            var selected = 'layui-form-selected'
            //表单select框
            var $parent = $(e.target).closest(parent)

            if ($parent.length > 0) {

                return
            }

            $(parent).removeClass(selected)

            $(parent).find('.st_tree').length > 0 ? $(parent).find('.st_tree').hide() : null
        })

        ptyxeleStoreData.isParse = true
    }

    Ptyxele.setting = function (option) {


        if (option == undefined || option == null) return


        var arr = new Array()

        if (option instanceof Array) {

            arr = option

        } else if (option instanceof Object) {
            arr.push(option)
        }

        for (var i = 0; i < arr.length; i++) {
            var ele = arr[i]

            if (!ele.module) {
                $.extend(true, ptyxeleStoreData, ele)
            } else {

                if (!ptyxeleStoreData.module) {
                    ptyxeleStoreData.module = new Object()
                }

                var module = ptyxeleStoreData.module

                if (typeof  ele.module == 'string') {

                    var moduleName = ele.module

                    delete ele.module

                    var mobj = new Object()

                    mobj[moduleName] = ele

                    $.extend(true, module, mobj)


                } else if (ele.module instanceof Array) {

                    var eleCopy = $.extend({}, ele)

                    delete ele.module

                    for (var j = 0; j < eleCopy.module.length; j++) {
                        var eleModuleName = eleCopy.module[j]

                        var mobj = new Object()

                        mobj[eleModuleName] = ele

                        $.extend(true, module, mobj)

                    }
                }


            }

        }
    }

    Ptyxele.dictName = function (dictType, code) {

        if (!dictType) return

        var dict = Ptyxele.prototype.getDict(dictType)

        for (var i = 0; i < dict.length; i++) {
            var obj = dict[i]

            if (obj.dictCode == code) {
                return obj.dictName
            }
        }

        return ''
    }

    Ptyxele.PTYXELE = 'ptyxele'

    Ptyxele.LINK = 'ptyxlink'

    Ptyxele.NODE_FORM = 'ptyx-form'

    Ptyxele.FORM_FN = 'ptyxele.form.fn'

    Ptyxele.PREFIX = 'ptyx-'

    Ptyxele.COMMON_MODULE = ['ptyx-data']

    Ptyxele.MUDEULS = [

        // 日期组件
        , 'ptyx-date'

        // 上传文件组件
        , 'ptyx-load'

        // 集团选择
        , 'ptyx-group'

        // 商品选择
        , 'ptyx-goods'

        // 产品选择
        , 'ptyx-product'

        // 供应商选择
        , 'ptyx-supplier'

        // 采购商选择
        , 'ptyx-buyer'

        // 厂家选择
        , 'ptyx-factory'

        // 单位选择
        , 'ptyx-unit'

        // 运营人员选择
        , 'ptyx-operator'

        // 省份
        , 'ptyx-province'

        // 城市
        , 'ptyx-city'

        // 地区
        , 'ptyx-area'

        // lay编辑器
        , 'ptyx-edit'

        // 百度编辑器
        , 'ptyx-uedit'

        // tip提示
        , 'ptyx-tip'

        // 树
        , 'ptyx-tree'

        //商品分类
        , 'ptyx-classify'

        //表单
        , 'ptyx-form'

        //字典库
        , 'ptyx-dict'

        //品牌
        , 'ptyx-brand'

        //销售客户
        , 'ptyx-salecustomer'

        //账户
        , 'ptyx-account'

        //商品分类下拉框
        , 'ptyx-goodssort'

        //采购目录-通用名称
        , 'ptyx-pcommonname'

        //采购目录-单位
        , 'ptyx-putil'

        //采购目录-规格
        , 'ptyx-pspec'

        //采购目录-厂家
        , 'ptyx-pfactory'

        // 采购商 收货地址
        , 'ptyx-daddress'



    ]

    Ptyxele.FUNCTIONAL = [

        // 下来框主题
        , 'ptyx-theme'

        // 多选属性
        , 'ptyx-box'

        // 默认主题
        , 'ptyx-theme-default'

        // 经典主题
        , 'ptyx-theme-classic'

        // 请求地址
        , 'ptyx-url'

        // 格式这里指的是日期格式
        , 'ptyx-format'

        // 省市区联动属性
        , 'ptyx-link'

        // 可读属性
        , 'readonly'
    ]

    Ptyxele.UTIL = new Object()
    //解析标签值
    Ptyxele.UTIL.parseQuickAttrValue = function (value) {
        if (!value || !$.trim(value)) {
            return
        }

        value = value.replace(/\s/g, '')


        if (value.indexOf('function') != -1) {
            throw new Error('暂不支持回调函数写法')
        }


        if (value.indexOf('/') != -1) {
            throw new Error('暂不支持注释或者正则写法')
        }


        if (value.match(/['"]{1}/)) {
            throw new Error('语法不正确')
        }

        if (value.substring(0, 1) != '{' || value.substring(value.length - 1, value.length) != '}') {
            throw new Error('语法不正确')
        }


        // 先处理中括号的数据
        var newVal = ''

        var signType = 0
        var word = ''
        var rep = /(^[0-9]*$)|(^true$)|(^false$)/

        for(var i =0;i<value.length;i++){
            // if(!isNaN(i)) continue

            var ele = value[i]

            signType = ele == ':' ? 1 : ele == '[' ? 2 : signType
            newVal += ele == '[' ? ':[' : ''

            if (signType == 1 && (ele == '}' || ele == ',')) {
                word = word.replace(':', '')
                newVal += rep.test(word) ? ":" + word : ":'" + word + "'"
                signType = 0
                word = ''
            }

            if (signType == 2 && (ele == ']' || ele == ',')) {
                var newWord = word.indexOf(':[') != -1 ? word.substring(2, word.length) : word.substring(0, 1) == ',' ? word.substring(1) : word

                if (!rep.test(newWord)) {

                    if (ele == ']') {
                        newVal += "'" + newWord + "'"
                    } else {
                        newVal += "'" + newWord + "',"
                    }
                } else {
                    if (ele == ']') {
                        newVal += newWord
                    } else {
                        newVal += newWord + ","
                    }
                }

                if (ele == ']') {
                    signType = 0
                }
                word = ''
            }

            if (signType == 0) {
                newVal += ele
            } else {
                word += ele
            }
        }
        return newVal

    }

    Ptyxele.UTIL.parseQuickAttrValueObj = function (value) {

        var currVal = ''
        var storeType = new Array()
        var newValue = ''

        var rep = /(^[0-9]*$)|(^true$)|(^false$)/

        for (var i = 0; i < value.length; i++) {
            var char = value[i]

            if (char == '{') {
                newValue += '{'
                continue
            }

            if (char == ':') {
                if (currVal) {
                    newValue += '"' + currVal + '":'
                    currVal = ''
                } else {
                    newValue += ':'
                }
                continue
            }

            if (char == '[') {
                newValue += '['
                continue
            }

            if (char == ',') {
                if (!currVal) {
                    newValue += ','
                } else {
                    if (rep.test(currVal)) {
                        newValue += currVal + ','
                    } else {
                        newValue += '"' + currVal + '",'
                    }
                    currVal = ''
                }
                continue
            }

            if (char == '}') {
                if (rep.test(currVal)) {
                    newValue += currVal + '}'
                } else {
                    newValue += '"' + currVal + '"}'
                }
                currVal = ''
                continue
            }

            if (char == ']') {
                if (!currVal) {
                    newValue += ']'
                } else {
                    if (rep.test(currVal)) {
                        newValue += currVal + ']'
                    } else {
                        newValue += '"' + currVal + '"]'
                    }
                    currVal = ''
                }
                continue
            }

            currVal += char
        }

        return JSON.parse(newValue)
    }

    //UUID生成
    Ptyxele.UTIL.uuid = function uuid(len, radix) {
        var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        var uuid = [], i;
        radix = radix || chars.length;

        if (len) {
            // Compact form
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
        } else {
            // rfc4122, version 4 form
            var r;

            // rfc4122 requires these characters
            uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
            uuid[14] = '4';

            // Fill in random data.  At i==19 set the high bits of clock sequence as
            // per rfc4122, sec. 4.1.5
            for (i = 0; i < 36; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random() * 16;
                    uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                }
            }
        }

        return uuid.join('');
    }

    Ptyxele.prototype.getModule = function (key) {

        if (ptyxeleStoreData.module) {
            return ptyxeleStoreData.module[key]
        } else {
            return {}
        }
    }

    Ptyxele.prototype.getParams = function () {
        var dataCopy = $.extend({}, ptyxeleStoreData)
        delete  dataCopy.module
        return dataCopy
    }

    Ptyxele.prototype.mergeOption = function () {

        var data = this.$element.data(Ptyxele.PTYXELE)

        if (!data) {

            if (!this.options.module) throw new Error('未指定要初始化组件')


            var stat = $.inArray(Ptyxele.PREFIX + this.options.module, Ptyxele.MUDEULS)

            if (stat == -1) throw new Error('未找到可以初始化的组件')


            data = {
                module: this.options.module
                , ptyxele_module: Ptyxele.PREFIX + this.options.module
            }

            this.$element.data(Ptyxele.PTYXELE, data)
        }


        var optData = new Object()

        $.extend(true, optData, this.getModule(data.module), this.options, data.data)

        this.options = optData

        if (data.ptyxele_extend) {
            var extend = data.ptyxele_extend
            var extendData = new Object()
            $.each(extend, function (k, v) {

                if (k == 'ptyx-link') {
                    extendData.link = v
                }

                if (k == 'ptyx-theme-default') extendData.theme = 'default'

                if (k == 'ptyx-theme-classic') extendData.theme = 'classic'

                if (k == 'ptyx-box') {
                    if (v == '') {
                        extendData.box = true
                    } else if (v == 'false') {
                        extendData.box = false
                    }
                }

                if (k == 'ptyx-url') {
                    if (v) {
                        extendData.url = v
                    }
                }

                if (k == 'readonly') {
                    extendData.readonly = true
                }

                if(k == 'ptyx-format'){
                    extendData.format = v
                }
            })

            $.extend(true, this.options, extendData)
        }

        if (this.options.link) {
            var $parent = $(this.options.link)

            if ($parent.length > 0) {
                $parent.data(Ptyxele.LINK, this.$element)
            }

        }

        var placeholder = this.$element.attr('placeholder')
        if (placeholder) {
            $.extend(true, this.options, {placeholder: placeholder})
            this.$element[0].removeAttribute('placeholder')
        } else {
            if (this.options.placeholder) {
                $.extend(true, this.options, {placeholder: this.options.placeholder[data.module]})
            }
        }

        // if (this.options.value) {
        //     this.value = this.options.value
        // }
    }

    Ptyxele.prototype.getDict = function (dictType) {

        Ptyxele()


        if (!dictType) {
            return {}
        }

        var dict = dictStoreData[dictType]

        if (dict) {
            return dict
        }

        var module = this.getModule('dict')

        if (!module || !module.url) throw  new Error('该组件不存在或者请求地址不存在')


        $.ajax({
            url: module.url
            , dataType: 'json'
            , data: {dictType: dictType}
            , async: false
            , success: function (res) {

                if (!res.successful) {
                    if (res.msg) {
                        throw new Error(res.msg)
                    }
                    throw new Error('数据请求失败')
                } else {
                    if (res.result) {
                        dictStoreData[dictType] = res.result
                    }
                }
            }
            , error: function (e) {
                throw (e)
            }
        })

        return dictStoreData[dictType]

    }


}(jQuery);

/**
 * 节点监听
 * Created by chenzp on 18-1-30.
 */
+function () {

    'use strict';

    var PtyxeleObserve = function () {

        this.initObserve();
    }


    PtyxeleObserve.UN_OBSERVER_NODE = [
        'BODY'
        , 'HTML'
        , 'SCRIPT'
    ]

    PtyxeleObserve.OBSERVER_TYPE = {
        ATTRIBUTES: 'ATTRIBUTES'
        , CHILDLIST: 'CHILDLIST'
    }


    PtyxeleObserve.CONFIG = {


        // 节点观察者默认是document
        observer: document

        , mutation_config: {
            childList: true, // 只监听:子节点的新增和删除
            attributes: true, // 决定会不会监听属性
            attributeOldValue: true,
            subtree: true, // 同时监听子节点的 characterData、attributes、childList三种状态
            attributeFilter: $.merge(new Array(), Ptyxele.MUDEULS, Ptyxele.FUNCTIONAL) // 这个筛选出要监听的属性
        }
    }


    //初始化观察者对象
    PtyxeleObserve.prototype.initObserve = function () {

        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver

        // 兼容性ie11+、Safar6(需要-webkit-)
        if (!window.MutationObserver) {
            this.ie8ParseChangeNOdes()
            return
        }

        var $this = this

        var observer = new MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {

                    var l = new Date().getTime();

                    $this.parseChangeNodes(mutation)

                    var i = new Date().getTime();

                    console.debug('解析ptyx-×  属性节点耗时：' + (i - l) + 'ms');
                }
            )
        });

        observer.observe(PtyxeleObserve.CONFIG.observer, PtyxeleObserve.CONFIG.mutation_config);// 开始做监听动作
    }


    //解析变化的节点
    PtyxeleObserve.prototype.parseChangeNodes = function (mutation) {

        var $this = this

        var nodeName = mutation.target.tagName
        var type = mutation.type.toUpperCase()

        // console.info(mutation);

        if (nodeName && $.inArray(nodeName, PtyxeleObserve.UN_OBSERVER_NODE) == -1) {


            if (type == PtyxeleObserve.OBSERVER_TYPE.CHILDLIST) {
                if (!mutation.addedNodes && mutation.addedNodes.length == 0) {
                    return
                }

                $this.parseAddNode(mutation)
                return
            }

            if (type == PtyxeleObserve.OBSERVER_TYPE.ATTRIBUTES) {
                $this.parseChangeAttr(mutation)
            }

        }

    }

    //处理属性变化
    PtyxeleObserve.prototype.parseChangeAttr = function (mutation) {
        var attrName = mutation.attributeName

        if (!/^ptyx{1}.*$/.test(attrName)) {
            return
        }

        var $target = $(mutation.target)
        $target.updatePtyxeleResolver(mutation)
    }


    //处理添加新节点
    PtyxeleObserve.prototype.parseAddNode = function (mutation) {
        var addNodes = mutation.addedNodes

        for (var i = 0; i < addNodes.length; i++) {
            var $node = $(addNodes[i])
            var attrs = addNodes[i].attributes

            if (!attrs) {
                continue
            }

            var isTarget = false
            $.each(attrs, function (k, v) {

                if (!/^ptyx{1}.*$/.test(v.name)) {
                    return true
                }

                if ($.inArray(v.name, Ptyxele.MUDEULS) != -1) {
                    isTarget = true
                    return false
                }
            })


            if (isTarget) {

                console.debug('是要处理的对象');

                $node.ptyxeleResolver()
            }

            //针对ptyx-form中的元素处理
            var tagName = addNodes[i].tagName


            if (tagName == 'INPUT' || tagName == 'SELECT') {
                $node.trigger('create.form.ptyxele-api')

                if ($node.ptyxeleVerify) {
                    $node.ptyxeleVerify()
                }
            }

            if (tagName == 'FORM' && $node[0].hasAttribute('ptyx-form')) {
                $node.on('submit', function () {
                    $(this).submit()
                })
            }


        }

        // console.info('添加新节点：'+mutation.target.tagName);

    }


    //兼容IE8使用定时器处理
    PtyxeleObserve.prototype.ie8ParseChangeNOdes = function () {


        var $$this = this

        var arr = Ptyxele.MUDEULS.toString().split(',')
        var filter = ''
        for (var i = 0; i < arr.length; i++) {
            var ele = arr[i]
            if (!ele) {
                continue
            }
            if (ele == 'ptyx-data') {
                continue
            }
            if (i == arr.length - 1) {
                filter += '[' + ele + '],[ptyx-data*="module:"]'
            } else {
                filter += '[' + ele + '],'
            }

        }


        setInterval(function () {
            // var ls = new Date().getTime()

            $(filter).each(function () {
                $(this).ptyxeleIe8Resolver()
            })

            // var le = new Date().getTime()
            //
            // console.info('查找节点耗时：'+(le-ls)+'ms');


        }, 200)

    }

    new PtyxeleObserve()

}(jQuery);

/**
 * 标签解析器
 * Created by chenzp on 18-1-30.
 */
+function () {

    var PtyxeleResolver = function (element, options) {
        this.$element = $(element)
        this.options = $.extend({}, PtyxeleResolver.DEFAULTS, options)

        if (!window.MutationObserver) {
            this.ie8ParseAttr()
        } else {
            this.parseAttrMain()
        }

    }

    //专门为IE8设置
    PtyxeleResolver.IE_CONTAINER = new Object()

    PtyxeleResolver.PACE = 'ptyxele.resolver'

    PtyxeleResolver.PARSE = 'ptyxele.resolver.parse'

    PtyxeleResolver.DEFAULTS = {
        /**
         *属性模块匹配的前缀
         */
        module_rep: /(^ptyx{1}.*$)|(^readonly{1}$)/
        /**
         * 模块前缀
         */
        , module_prefix: 'ptyxele'
    }

    //更新变化属性
    PtyxeleResolver.prototype.updateAttr = function (mutation) {

        if (!mutation) {
            return
        }

        var module = this.options.module_prefix + '_module'
        var attrName = mutation.attributeName
        var $target = $(mutation.target)

        var dataStore = new Object()
        if ($.inArray(attrName, Ptyxele.MUDEULS) != -1) {
            var data = {data: null}
            try {
                var value = $target.attr(attrName)
                data[module] = attrName
                if (value) {
                    var valData = Ptyxele.UTIL.parseQuickAttrValueObj(value)
                    data.data = valData
                }
                dataStore.moduleAttr = data
            } catch (e) {
                throw new Error('标签解析失败:' + e)
            }

        } else if ($.inArray(attrName, Ptyxele.COMMON_MODULE) != -1) {
            var data = {data: null}
            try {
                var value = $target.attr(attrName)
                if (value) {
                    var valData = Ptyxele.UTIL.parseQuickAttrValueObj(value)

                    if (valData.module) {

                        if ($.inArray('ptyx-' + valData.module, Ptyxele.MUDEULS) == -1) {
                            throw new Error('未找到可以加载插件类型')
                        }
                        data[module] = 'ptyx-' + valData.module
                    }
                    data.data = valData
                }
                dataStore.commonAttr = data
            } catch (e) {
                throw new Error('标签解析失败:' + e)
            }

        } else if ($.inArray(attrName, Ptyxele.FUNCTIONAL) != -1) {

            var value = $target.attr(attrName)
            dataStore.extendAttr[attrName] = value ? value : ''
        }

        var eledata = this.$element.data(this.options.module_prefix)
        if (eledata) {
            if (dataStore.moduleAttr) {
                if (eledata[module] && dataStore.moduleAttr[module] && eledata[module] != dataStore.moduleAttr[module]) {
                    throw new Error('加载插件类型不一致')
                }

                $.extend(true, eledata, dataStore.moduleAttr)

                this.$element.data(this.options.module_prefix, eledata)

            }

            if (dataStore.commonAttr) {
                var seiriData = new Object()
                seiriData.data = new Object()

                if (!eledata[module] && dataStore.commonAttr[module]) {
                    seiriData[module] = dataStore.commonAttr[module]
                }

                if (!seiriData[module] && !eledata[module]) {
                    throw new Error('未指定要记载插件类型')
                }

                var moduleType = ''
                if (seiriData[module]) {
                    moduleType = seiriData[module]
                } else {
                    moduleType = eledata[module]
                }

                var moduleAttrVal = $target.attr(moduleType)
                var moduleAttr = Ptyxele.UTIL.parseQuickAttrValueObj(moduleAttrVal)


                for (n in dataStore.commonAttr.data) {
                    if (!moduleAttr[n]) {
                        seiriData.data[n] = dataStore.commonAttr[n]
                    }
                }

                $.extend(true, eledata, seiriData)
                this.$element.data(this.options.module_prefix, eledata)
            }

            if (dataStore.extendAttr) {
                var seiriData = new Object()
                seiriData[this.options.module_prefix + '_extend'] = dataStore.extendAttr
                $.extend(true, eledata, seiriData)
                this.$element.data(this.options.module_prefix, eledata)
            }
        } else {
            if (dataStore.moduleAttr) {
                if (!dataStore.moduleAttr[module]) {
                    throw new Error('未指定插件类型')
                }
            }

            if (dataStore.commonAttr) {
                if (!dataStore.commonAttr[module]) {
                    throw new Error('未指定插件类型')
                }
            }

            this.$element.data(this.options.module_prefix, dataStore)
        }

        this.$element.data(PtyxeleResolver.PARSE, 1)
    }

    //解析属性值 isParse 默认为undifed  解析完状态：1，失败为-1
    PtyxeleResolver.prototype.parseAttrMain = function (myContainer) {

        var $element = this.$element
        var $this = this
        var module = $this.options.module_prefix + '_module'

        var data = $element.data(PtyxeleResolver.PARSE)
        if (data == 1) {
            return
        }

        var attrs = this.$element[0].attributes


        if (!attrs) {
            return
        }

        var dataStore = new Object()

        $.each(attrs, function (k, v) {

            if (!$this.options.module_rep.test(v.name)) {
                return true
            }

            if ($.inArray(v.name, Ptyxele.MUDEULS) != -1) {
                var data = {data: null}
                if (v.value) {
                    var newVal = Ptyxele.UTIL.parseQuickAttrValue(v.value)
                    var valData = {}
                    if (newVal) {
                        valData = eval('(' + newVal + ')')
                    }
                    data.data = valData
                    if (myContainer) {
                        myContainer.module_data = valData
                    }
                } else {

                    if (myContainer) {
                        myContainer.module_data = {}
                    }
                }
                data[module] = v.name
                dataStore.moduleAttr = data
            } else if ($.inArray(v.name, Ptyxele.COMMON_MODULE) != -1) {
                var data = {data: null}
                if (v.value) {
                    var newVal = Ptyxele.UTIL.parseQuickAttrValue(v.value)
                    var valData = {}
                    if (newVal) {
                        valData = eval('(' + newVal + ')')
                    }

                    if (valData.module) {

                        if ($.inArray('ptyx-' + valData.module, Ptyxele.MUDEULS) == -1) {
                            throw new Error('未找到可以加载插件类型')
                        }
                        data[module] = 'ptyx-' + valData.module
                        delete valData.module

                    }
                    data.data = valData
                    if (myContainer) {
                        myContainer.common_data = valData
                    }
                } else {
                    if (myContainer) {
                        myContainer.common_data = {}
                    }
                }

                dataStore.commonAttr = data


            } else if ($.inArray(v.name, Ptyxele.FUNCTIONAL) != -1) {

                if (!dataStore.extendAttr) {
                    dataStore.extendAttr = new Object()
                }
                dataStore.extendAttr[v.name] = v.value ? v.value : ''
            }
        })


        if (!dataStore.moduleAttr && !dataStore.commonAttr) {
            // 添加解析失败状态
            $element.data(PtyxeleResolver.PARSE, -1)
            throw new Error($element[0].tagName + '未设定需要初始化指定的模块')
        }

        if ((dataStore.moduleAttr && !dataStore.moduleAttr[module]) && (dataStore.commonAttr && !dataStore.commonAttr[module])) {
            // 添加解析失败状态
            $element.data(PtyxeleResolver.PARSE, -1)
            throw new Error($element[0].tagName + '未设定需要初始化指定的模块')
        }

        var option = new Object()

        $.extend(true, option, dataStore.commonAttr, dataStore.moduleAttr)

        if (dataStore.moduleAttr && dataStore.moduleAttr[module]) {
            option[module] = dataStore.moduleAttr[module]
            option.module = dataStore.moduleAttr[module].replace('ptyx-', '')
        } else {
            option[module] = dataStore.commonAttr[module]
            if (dataStore.commonAttr[module]) {
                option.module = dataStore.commonAttr[module].replace('ptyx-', '')
            }

        }

        if (dataStore.extendAttr) {
            option[$this.options.module_prefix + '_extend'] = dataStore.extendAttr
        }

        $element.data(this.options.module_prefix, option)

        // 添加已解析状态
        $element.data(PtyxeleResolver.PARSE, 1)
    }

    //低版本浏览器兼容性处理，这里主要针对IE8做处理
    PtyxeleResolver.prototype.ie8ParseAttr = function () {
        var $element = this.$element
        var $this = this
        var module = $this.options.module_prefix + '_module'

        var container = PtyxeleResolver.IE_CONTAINER
        var uuid = $element.data('ptyxele.static.uuid')

        if (!uuid) {
            uuid = this.uuid(8, 16)
            $element.data('ptyxele.static.uuid', uuid)
            container[uuid] = {}
            container[uuid].handleStatus = 'end'
        }

        var myContainer = container[uuid]
        var handleStatus = myContainer.handleStatus

        if (handleStatus == 'handle') {
            return
        }
        myContainer.handleStatus = 'handle'

        var parseStat = $element.data(PtyxeleResolver.PARSE)

        var eventSpace = ''

        if (!parseStat && parseStat != 1) {//未解析
            this.parseAttrMain(myContainer)
            eventSpace = this.getEventSpace('create')
        } else {//已解析

            var attrs = this.$element[0].attributes

            if (!attrs) {
                $element.data(PtyxeleResolver.PARSE, 1)
                return
            }

            var dataStore = new Object()

            $.each(attrs, function (k, v) {

                if (!$this.options.module_rep.test(v.name)) {
                    return true
                }

                if ($.inArray(v.name, Ptyxele.MUDEULS) != -1) {

                    var data = {data: null}
                    if (v.value) {
                        var newVal = Ptyxele.UTIL.parseQuickAttrValue(v.value)
                        var valData = eval('(' + newVal + ')')


                        if (!myContainer.module_data) {
                            myContainer.module_data = {}
                        }

                        var isEqual = $this.isEqual(valData, myContainer.module_data)

                        if (isEqual) {
                            return true
                        }

                        data.data = valData
                        myContainer.module_data = valData
                    } else {
                        if (!myContainer.module_data) {
                            return true
                        }
                        myContainer.module_data = v.value
                    }
                    data[module] = v.name
                    dataStore.moduleAttr = data
                } else if ($.inArray(v.name, Ptyxele.COMMON_MODULE) != -1) {
                    var data = {data: null}
                    if (v.value) {
                        var newVal = Ptyxele.UTIL.parseQuickAttrValue(v.value)
                        var valData = eval('(' + newVal + ')')

                        if (!myContainer.common_data) {
                            myContainer.common_data = {}
                        }

                        var isEqual = $this.isEqual(myContainer.common_data, valData)
                        if (isEqual) {
                            return true
                        }

                        if (valData.module) {

                            if ($.inArray('ptyx-' + valData.module, Ptyxele.MUDEULS) == -1) {
                                throw new Error('未找到可以加载插件类型')
                            }
                            data[module] = 'ptyx-' + valData.module
                            delete valData.module

                        }
                        data.data = valData
                        myContainer.common_data = valData
                    } else {
                        if (!myContainer.common_data) {
                            return true
                        }
                        myContainer.common_data = v.value
                    }

                    dataStore.commonAttr = data


                } else if ($.inArray(v.name, Ptyxele.FUNCTIONAL) != -1) {

                    if (!dataStore.extendAttr) {
                        dataStore.extendAttr = new Object()
                    }
                    dataStore.extendAttr[v.name] = v.value ? v.value : ''
                }


            })

            var eledata = this.$element.data(this.options.module_prefix)
            if (eledata) {
                if (dataStore.moduleAttr) {
                    if (eledata[module] && dataStore.moduleAttr[module] && eledata[module] != dataStore.moduleAttr[module]) {
                        throw new Error('加载插件类型不一致')
                    }

                    $.extend(true, eledata, dataStore.moduleAttr)

                    this.$element.data(this.options.module_prefix, eledata)

                }

                if (dataStore.commonAttr) {
                    var seiriData = new Object()
                    seiriData.data = new Object()

                    if (!eledata[module] && dataStore.commonAttr[module]) {
                        seiriData[module] = dataStore.commonAttr[module]
                    }

                    if (!seiriData[module] && !eledata[module]) {
                        throw new Error('未指定要记载插件类型')
                    }

                    var moduleType = ''
                    if (seiriData[module]) {
                        moduleType = seiriData[module]
                    } else {
                        moduleType = eledata[module]
                    }

                    var moduleAttrVal = $target.attr(moduleType)
                    var newVal = Ptyxele.UTIL.parseQuickAttrValue(moduleAttrVal)
                    var moduleAttr = eval('(' + newVal + ')')


                    for (n in dataStore.commonAttr.data) {
                        if (!moduleAttr[n]) {
                            seiriData.data[n] = dataStore.commonAttr[n]
                        }
                    }

                    $.extend(true, eledata, seiriData)
                    this.$element.data(this.options.module_prefix, eledata)
                }

                if (dataStore.extendAttr) {
                    var seiriData = new Object()
                    seiriData[this.options.module_prefix + '_extend'] = dataStore.extendAttr
                    $.extend(true, eledata, seiriData)
                    this.$element.data(this.options.module_prefix, eledata)
                }
            } else {
                if (dataStore.moduleAttr) {
                    if (!dataStore.moduleAttr[module]) {
                        throw new Error('未指定插件类型')
                    }
                }

                if (dataStore.commonAttr) {
                    if (!dataStore.commonAttr[module]) {
                        throw new Error('未指定插件类型')
                    }
                }

                this.$element.data(this.options.module_prefix, dataStore)
            }

            this.$element.data(PtyxeleResolver.PARSE, 1)

            eventSpace = this.getEventSpace('update')
        }
        $element.trigger(eventSpace)

        $element.data('ptyxele.handle.status', 'end')
    }

    //标签属性快捷写法处理
    PtyxeleResolver.prototype.parseQuickAttrValue = function (value) {
        if (!value || !$.trim(value)) {
            return
        }

        value = value.replace(/\s/g, '')


        if (value.indexOf('function') != -1) {
            throw new Error('暂不支持回调函数写法')
        }


        if (value.indexOf('/') != -1) {
            throw new Error('暂不支持注释或者正则写法')
        }


        if (value.match(/['"]{1}/)) {
            throw new Error('语法不正确')
        }

        if (value.substring(0, 1) != '{' || value.substring(value.length - 1, value.length) != '}') {
            throw new Error('语法不正确')
        }


        // 先处理中括号的数据
        var newVal = ''

        var signType = 0
        var word = ''
        var rep = /(^[0-9]*$)|(^true$)|(^false$)/
        for (i in value) {
            var ele = value[i]

            signType = ele == ':' ? 1 : ele == '[' ? 2 : signType
            newVal += ele == '[' ? ':[' : ''

            if (signType == 1 && (ele == '}' || ele == ',')) {
                word = word.replace(':', '')
                newVal += rep.test(word) ? ":" + word : ":'" + word + "'"
                signType = 0
                word = ''
            }

            if (signType == 2 && (ele == ']' || ele == ',')) {
                var newWord = word.indexOf(':[') != -1 ? word.substring(2, word.length) : word.substring(0, 1) == ',' ? word.substring(1) : word

                if (!rep.test(newWord)) {

                    if (ele == ']') {
                        newVal += "'" + newWord + "'"
                    } else {
                        newVal += "'" + newWord + "',"
                    }
                } else {
                    if (ele == ']') {
                        newVal += newWord
                    } else {
                        newVal += newWord + ","
                    }
                }

                if (ele == ']') {
                    signType = 0
                }
                word = ''
            }

            if (signType == 0) {
                newVal += ele
            } else {
                word += ele
            }

        }
        return newVal

    }

    //获取事件触发空间地址
    PtyxeleResolver.prototype.getEventSpace = function (type) {

        if (!type) {
            return null
        }

        var data = this.$element.data(PtyxeleResolver.PARSE)
        var module = this.$element.data(this.options.module_prefix).module

        if (type == 'create' || type == 'update') {
            return type + '.' + module + '.ptyxele-api'
        }
        return null
    }

    //UUID生成
    PtyxeleResolver.prototype.uuid = function uuid(len, radix) {
        var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        var uuid = [], i;
        radix = radix || chars.length;

        if (len) {
            // Compact form
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
        } else {
            // rfc4122, version 4 form
            var r;

            // rfc4122 requires these characters
            uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
            uuid[14] = '4';

            // Fill in random data.  At i==19 set the high bits of clock sequence as
            // per rfc4122, sec. 4.1.5
            for (i = 0; i < 36; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random() * 16;
                    uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                }
            }
        }

        return uuid.join('');
    }

    PtyxeleResolver.prototype.isEqual = function equals(x, y) {
        var in1 = x instanceof Object;
        var in2 = y instanceof Object;
        if (!in1 || !in2) {
            return x === y;
        }
        if (Object.keys(x).length !== Object.keys(y).length) {
            return false;
        }
        for (var p in x) {
            var a = x[p] instanceof Object;
            var b = y[p] instanceof Object;
            if (a && b) {
                return equals(x[p], y[p]);
            }
            else if (x[p] !== y[p]) {
                return false;
            }
        }

        return true;
    }

    function Plugin() {
        return this.each(function () {
            var $this = $(this)
            var data = $this.data(PtyxeleResolver.PACE)

            if (!data) $this.data(PtyxeleResolver.PACE, (data = new PtyxeleResolver(this)))
            var eventSpace = data.getEventSpace('create')
            $this.trigger(eventSpace)
        })
    }

    function Update(mutation) {
        return this.each(function () {
            var $this = $(this)
            var data = $this.data(PtyxeleResolver.PACE)

            if (!data) {
                $this.data(PtyxeleResolver.PACE, (data = new PtyxeleResolver(this)))
            } else {
                data.updateAttr(mutation)
            }
            var eventSpace = data.getEventSpace('update')
            $this.trigger(eventSpace)
        })
    }

    function Parse() {
        var $this = $(this)
        var data = $this.data(PtyxeleResolver.PACE)
        if (!data) {
            $this.data(PtyxeleResolver.PACE, (data = new PtyxeleResolver(this)))
        }
    }

    function Ie8Plugin() {
        return this.each(function () {
            var $this = $(this)
            var data = $this.data(PtyxeleResolver.PACE)
            if (!data) {
                $this.data(PtyxeleResolver.PACE, (data = new PtyxeleResolver(this)))
            }
        })
    }


    $.fn.ptyxeleResolver = Plugin

    $.fn.updatePtyxeleResolver = Update

    $.fn.parsePtyxeleResolver = Parse

    $.fn.ptyxeleIe8Resolver = Ie8Plugin


}(jQuery);

/**
 * Created by chenzp on 18-1-30.
 */
+function ($) {
    'use strict';

    var PtyxeleDate = function (ele, options) {
        this.$element = $(ele)
        this.options = $.extend({}, PtyxeleDate.DEFAULTS, options)
        this.init()
    }

    PtyxeleDate.PACE = 'ptyx.date'

    PtyxeleDate.TAG = 'ptyx-date'

    PtyxeleDate.VERSION = '1.0.0'

    PtyxeleDate.DEFAULTS = {
        /**
         * year    年选择器    只提供年列表选择
         * month    年月选择器    只提供年、月选择
         * date    日期选择器    可选择：年、月、日。type默认值，一般可不填
         * time    时间选择器    只提供时、分、秒选择
         * datetime    日期时间选择器    可选择：年、月、日、时、分、秒
         */
        type: 'date'

        /**
         * 类型：Boolean/String，默认值：false
         *如果设置 true，将默认采用 “ - ” 分割。 你也可以直接设置 分割字符。五种选择器类型均支持左右面板的范围选择。
         *
         *
         */
        , range: false
        /**
         * 类型：String，默认值：yyyy-MM-dd
         * 通过日期时间各自的格式符和长度，来设定一个你所需要的日期格式
         * yyyy    年份，至少四位数。如果不足四位，则前面补零
         * y    年份，不限制位数，即不管年份多少位，前面均不补零
         * MM    月份，至少两位数。如果不足两位，则前面补零。
         * M    月份，允许一位数。
         * dd    日期，至少两位数。如果不足两位，则前面补零。
         * d    日期，允许一位数。
         * HH    小时，至少两位数。如果不足两位，则前面补零。
         * H    小时，允许一位数。
         * mm    分钟，至少两位数。如果不足两位，则前面补零。
         * m    分钟，允许一位数。
         * ss    秒数，至少两位数。如果不足两位，则前面补零。
         * s    秒数，允许一位数。
         *
         * 通过上述不同的格式符组合成一段日期时间字符串，可任意排版，如下所示：
         * yyyy-MM-dd HH:mm:ss    2017-08-18 20:08:08
         * yyyy年MM月dd日 HH时mm分ss秒    2017年08月18日 20时08分08秒
         * yyyyMMdd    20170818
         * dd/MM/yyyy    18/08/2017
         * yyyy年M月    2017年8月
         * M月d日    8月18日
         * 北京时间：HH点mm分    北京时间：20点08分
         * yyyy年的M月某天晚上，大概H点    2017年的8月某天晚上，大概20点
         *
         *
         *
         */
        , format: 'yyyy-MM-dd'

        /**
         * 类型：string，默认值：min: '1900-1-1'
         *1.如果值为字符类型，则：年月日必须用 -（中划线）分割、时分秒必须用 :（半角冒号）号分割。这里并非遵循 format 设定的格式
         *2.如果值为整数类型，且数字＜86400000，则数字代表天数，如：min: -7，即代表最小日期在7天前，正数代表若干天后
         *3.如果值为整数类型，且数字 ≥ 86400000，则数字代表时间戳，如：max: 4073558400000，即代表最大日期在：公元3000年1月1日
         *
         */
        , min: '1900-1-1'
        /**
         *
         * 类型：string，默认值：max: '2099-12-31'
         *1.如果值为字符类型，则：年月日必须用 -（中划线）分割、时分秒必须用 :（半角冒号）号分割。这里并非遵循 format 设定的格式
         *2.如果值为整数类型，且数字＜86400000，则数字代表天数，如：min: -7，即代表最小日期在7天前，正数代表若干天后
         *3.如果值为整数类型，且数字 ≥ 86400000，则数字代表时间戳，如：max: 4073558400000，即代表最大日期在：公元3000年1月1日
         *
         */
        , max: '2099-12-31'
        /**
         * 类型：String，默认值：focus，如果绑定的元素非输入框，则默认事件为：click
         *
         *
         */
        , trigger: 'focus'
        /**
         * 如果设置: true，则控件默认显示在绑定元素的区域。通常用于外部事件调用控件，如：
         *
         *
         */
        , show: false
        /**
         * 类型：String，默认值：absolute
         * 用于设定控件的定位方式，有以下三种可选值：
         * abolute    绝对定位，始终吸附在绑定元素周围。默认值
         * fixed    固定定位，初始吸附在绑定元素周围，不随浏览器滚动条所左右。一般用于在固定定位的弹层中使用。
         * static    静态定位，控件将直接嵌套在指定容器中。
         * 注意：请勿与 show 参数的概念搞混淆。show为 true 时，控件仍然是采用绝对或固定定位。而这里是直接嵌套显示
         *
         */
        , position: 'absolute'
        /**
         *类型：Number，默认值：66666666
         *一般用于解决与其它元素的互相被遮掩的问题。如果 position 参数设为 static 时，该参数无效。
         *
         */
        , zIndex: 66666666
        /**
         * 类型：Boolean，默认值：true
         * 如果设置 false，将不会显示控件的底部栏区域
         */
        , showBottom: true
        /**
         * 类型：Array，默认值：['clear', 'now', 'confirm']
         * 右下角显示的按钮，会按照数组顺序排列，内置可识别的值有：clear、now、confirm
         */
        , btns: ['clear', 'now', 'confirm']
        /**
         * 类型：String，默认值：cn
         * 我们内置了两种语言版本：cn（中文版）、en（国际版，即英文版）。这里并没有开放自定义文字，是为了避免繁琐的配置。
         */
        , lang: 'cn'
        /**
         * 类型：String，默认值：default
         * 我们内置了多种主题，theme的可选值有：default（默认简约）、molv（墨绿背景）、#颜色值（自定义颜色背景）、grid（格子主题）
         */
        , theme: 'default'
        /**
         * 类型：Boolean，默认值：false
         * 我们内置了一些我国通用的公历重要节日，通过设置 true 来开启。国际版不会显示。
         */
        , calendar: false
        /**
         * 标注重要日子
         * 类型：Object，默认值：无
         * calendar 参数所代表的公历节日更多情况下是一个摆设。因此，我们还需要自定义标注重要日子，比如结婚纪念日？日程等？它分为以下两种：
         * 每年的日期    {'0-9-18': '国耻'}    0 即代表每一年
         * 每月的日期    {'0-0-15': '中旬'}    0-0 即代表每年每月（layui 2.1.1/layDate 5.0.4 新增）
         * 特定的日期    {'2017-8-21': '发布')
         *可同时设定多个
         * mark: {
         *  '0-10-14': '生日'
         * ,'0-12-31': '跨年' //每年12月31日
         * ,'0-0-10': '工资' //每个月10号
         * ,'2017-8-15': '' //具体日期
         * ,'2017-8-20': '预发' //如果为空字符，则默认显示数字+徽章
         * ,'2017-8-21': '发布'
         * }
         *
         *
         */
        , mark: null
        /**
         * 控件初始打开的回调
         * 控件在打开时触发，回调返回一个参数：初始的日期时间对象
         * @param date 得到初始的日期时间对象：{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
         */
        , ready: function (date) {

        }
        /**
         * 日期时间被切换后的回调
         *年月日时间被切换时都会触发。回调返回三个参数，分别代表：生成的值、日期时间对象、结束的日期时间对象
         * @param value 得到日期生成的值，如：2017-08-18
         * @param date 得到日期时间对象：{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
         * @param endDate 得结束的日期时间对象，开启范围选择（range: true）才会返回。对象成员同上。
         *
         */
        , change: function (value, date, endDate) {

        }

        /**
         * 控件选择完毕后的回调
         * @param value 得到日期生成的值，如：2017-08-18
         * @param date 得到日期时间对象：{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
         * @param endDate 得结束的日期时间对象，开启范围选择（range: true）才会返回。对象成员同上。
         *
         *
         */
        , done: function (value, date, endDate) {

        }

    }

    PtyxeleDate.prototype.init = function () {
        var data = new Object()
        data.elem = this.$element[0]

        this.mergeOption()

        $.extend(true, data, this.options)

        var opt = this.options

        if (opt.placeholder) {
            this.$element.attr('placeholder', opt.placeholder)
        }
        layui.use('laydate', function () {
            var laydate = layui.laydate
            //执行一个laydate实例
            laydate.render(data)
        })


    }

    PtyxeleDate.prototype.update = function (option) {
        var data = new Object()
        data.elem = this.$element[0]

        this.mergeOption()

        layui.use('laydate', function () {
            var laydate = layui.laydate
            //执行一个laydate实例
            laydate.render(data)
        })
    }


    //重写值
    PtyxeleDate.prototype.val = function (value) {
        if (value == undefined || value == null) {
            return this.$element[0].value
        } else {
            if (value.time) {
                var value = new Date(value.time).format(this.options.format)
                // return value == null || value == undefined ? oldVal.call(this.$element) : oldVal.call(this.$element, value)

                this.$element.attr('value', value)
            } else if (/^[0-9]+$/.test(value + '')) {
                var value = new Date(value).format(this.options.format)
                this.$element.attr('value', value)
            }else if(value == ''){
                this.$element.attr('value', value)
            } else {
                return value == null || value == undefined ? oldVal.call(this.$element) : oldVal.call(this.$element, value)
            }
        }
    }

    function Plugin(options) {

        return this.each(function () {
            var $this = $(this)

            var data = $this.data(PtyxeleDate.PACE)

            Ptyxele()

            if (!data) {

                var dd = $.extend(true, PtyxeleDate.prototype, Ptyxele.prototype, PtyxeleDate.prototype)

                $this.data(PtyxeleDate.PACE, (data = new dd.constructor(this, options)))
            }
        })
    }


    function Update(options) {
        return this.each(function () {
            var $this = $(this)

            var data = $this.data(PtyxeleDate.PACE)

            if (!data) {
                $this.data(PtyxeleDate.PACE, (data = new PtyxeleDate(this, options)))
            } else {
                data.update(options)
            }
        })
    }

    function ParseVal(value) {

        var $this = $(this), data = $this.data(Ptyxele.PTYXELE)

        if (!data) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }

        var module = data.module.replace(Ptyxele.PREFIX, '')


        if (module != 'date') {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        } else {
            data = $this.data(PtyxeleDate.PACE)
            if (data) {
                return data.val(value)
            } else {
                return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
            }
        }

    }

    Date.prototype.format = function (format) {
        var date = {
            "M+": this.getMonth() + 1,
            "d+": this.getDate(),
            "h+": this.getHours(),
            "H+": this.getHours(),
            "m+": this.getMinutes(),
            "s+": this.getSeconds(),
            "q+": Math.floor((this.getMonth() + 3) / 3),
            "S+": this.getMilliseconds()
        };
        if (/(y+)/i.test(format)) {
            format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
        }
        for (var k in date) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length == 1
                    ? date[k] : ("00" + date[k]).substr(("" + date[k]).length));
            }
        }
        return format;
    }

    var oldVal = $.fn.val
    $.fn.ptyxeledate = Plugin
    $.fn.ptyxeledateUpdate = Update

    $.fn.val = ParseVal


    $(window).on('load', function () {
        $('[ptyx-date],[ptyx-data*="module:date"]').each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxeledate()

        })
    })

    $(document).on('create.date.ptyxele-api', '[ptyx-date],[ptyx-data*="module:date"]', function () {
        $(this).ptyxeledate()
    })

    $(document).on('update.date.ptyxele-api', '[ptyx-date],[ptyx-data*="module:date"]', function () {
        $(this).ptyxeledateUpdate()
    })

}(jQuery);

/**
 * Created by chenzp on 18-3-22.
 */
+function ($) {

    var PtyxeleForm = function (ele) {
        this.$element = $(ele)
    }

    PtyxeleForm.PACE = 'ptyxele-form'

    PtyxeleForm.PARSE_STATUS = 'ptyxele.form.status'

    PtyxeleForm.SELECT_PACE = 'ptyxele.form.select'

    //初始化
    PtyxeleForm.prototype.init = function () {
        var tagName = this.$element[0].tagName

        var data = this.$element.data(Ptyxele.PTYXELE)

        if (data) return

        this.$element.hide()

        if (tagName == 'SELECT') {
            // this.initSelect()
            this.initLaySelect()

        } else if (tagName == 'INPUT') {

            var type = this.$element.attr('type')

            if (type == 'checkbox') {
                this.initChexkBox()
            } else if (type == 'radio') {
                this.initRadio()
            }
        }
    }

    //初始化表单
    PtyxeleForm.prototype.initForm = function () {
        //重写提交表单事件
        // this.$element.on('submit',$.proxy(this.formSubmitEvent,this))
    }

    PtyxeleForm.prototype.initEvent = function () {

    }

    //重写表单提交事件
    PtyxeleForm.prototype.formSubmitEvent = function (e) {
        var $target = $(e.currentTarget)


        var str = this.serializeArray()

        console.info(str)

        return false
    }

    //重写jquery serrializeArray
    PtyxeleForm.prototype.serializeArray = function () {
        var $this = this.$element
        return $this.map(function () {
            return this.elements ? $.makeArray(this.elements) : this
        }).filter(function () {

            return this.name && !this.disabled &&
                (this.checked
                    || /^(?:select|textarea)/i.test(this.nodeName)
                    || /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i.test(this.type)
                    || (/^(?:checkbox)/i.test(this.type) && (this.getAttribute('lay-skin') || this.getAttribute('data-value')) )
                    || (/^(?:radio)/i.test(this.type) && (this.getAttribute('data-value')))
                )
        }).map(function (i, elem) {
            var val = $(this).val()

            return val == null ? null : $.isArray(val) ? $.map(val, function (val, i) {
                return {
                    name: elem.name,
                    value: val.replace(/\r?\n/g, "\r\n")
                }
            }) : {
                name: elem.name,
                value: val.replace(/\r?\n/g, "\r\n")
            }
        }).get()
    }

    //重写jquery serialize
    PtyxeleForm.prototype.serialize = function () {
        return $.param(this.serializeArray())
    }

    //重写jquery submit
    PtyxeleForm.prototype.submit = function (data, fn) {
        if (fn == null) {
            fn = data;
            data = null;
        }

        return this.$element.trigger('submit');
    }

    //初始化下拉框
    PtyxeleForm.prototype.initSelect = function () {
        var $node = this.$element

        if(this.parseOver) return

        var $this = this

        var str = '  <div class="layui-unselect layui-form-select ptcs-select">' +
            '        <div class="layui-select-title">' +
            '            <input type="text"  class="layui-input layui-unselect" readonly/>' +
            '            <input type="hidden"/>' +
            '            <i class="layui-edge"></i>' +
            '        </div>' +
            '        <dl class="layui-anim layui-anim-upbit"></dl>' +
            '    </div>'

        var $str = $(str)

        this.$element.after($str)

        this.$select = $str

        var $options = this.$element.find('option')

        var $dl = $str.find('dl')

        $options.find('dd')

        var defaultName =  $node.attr('placeholder') ? $node.attr('placeholder'):'请选择'

        $str.find('input.layui-input').attr('placeholder',defaultName)

        var $checkdd = null

        for (var i = 0; i < $options.length; i++) {
            var $option = $options.eq(i)
            var val = $option.attr('value')

            if (!val && $option.text()) {
                defaultName = $option.text()
                continue
            }

            var $dd = $('<dd></dd>').attr('lay-value', val).html($option.text())

            if ($option.attr('selected')) {
                $checkdd = $dd
            }

            $dl.append($dd)
        }

        $dl.prepend('<dd lay-value="" class="layui-select-tips">' + defaultName + '</dd>')


        var selected = 'layui-form-selected'

        $str.find('input').on('click', function () {
            var selchecked = 'layui-form-selected'

            var parent = '.layui-unselect.layui-form-select'

            if ($str.hasClass(selected)) {
                $(parent).removeClass(selchecked)
                $str.removeClass(selected)
            } else {
                $(parent).removeClass(selchecked)
                $str.addClass(selected)
            }
        })


        $str.find('dd').on('click', function () {

            var oldVal = $this.$element.val()

            var val = $(this).attr('lay-value')

            $(this).closest('dl').find('.layui-this').removeClass('layui-this')

            $str.find('.layui-input').attr('placeholder', $(this).text())

            if (val) {
                $(this).addClass('layui-this')
                $str.find('input[type="hidden"]').val(val)
            } else {
                $str.find('input[type="hidden"]').val("")
            }

            $this.$element.find('option[value="' + val + '"]').prop('selected', true)


            var currVal = $this.$element.val()

            $this.$select.removeClass(selected)

            //值不一样触发change事件
            if(oldVal != currVal) {
                $this.$element.trigger('change')
            }
        })

        // $(document).on('click', function (e) {
        //     var $parent = $(e.target).closest('.ptcs-select')
        //
        //     if ($parent.length > 0){
        //         return
        //     }
        //
        //     $('.layui-unselect.layui-form-select').removeClass(selected)
        // })

        if ($checkdd) {
            $checkdd.trigger('click')
        }else{
            $dl.find('.layui-select-tips').trigger('click')
        }

        this.parseOver = true
    }


    //初始化layui已经加载的select
    PtyxeleForm.prototype.initLaySelect = function () {
        var $node = this.$element

        if(this.parseOver) return

        if(!$node.next().hasClass('layui-unselect')) {
            this.initSelect()
            return
        }else{
            var $parent = $node.next()
            $parent.find('dl>dd').on('click',function () {
                $node.trigger('click')
                var val = $node.val()

                var ptyxVal = $node.data('ptyx-value')

                if(ptyxVal == undefined){
                    $node.data('ptyx-value',val)
                    $node.trigger('change')
                }else{

                    if(ptyxVal != val) {
                        $node.trigger('change')
                        $node.data('ptyx-value',val)
                    }
                }

            })
        }
    }

    //初始化复选框
    PtyxeleForm.prototype.initChexkBox = function () {
        var $this = this
        var $ele = this.$element
        var data = $ele.data('value')
        var value = $ele.val().split(',')
        var style = $ele.attr('lay-skin')

        this.$element.prop('checked', 'checked')


        if (data) {
            data = Ptyxele.UTIL.parseQuickAttrValueObj(data)

        }

        var isDefault = false

        if ($.inArray('on', value) != -1) {
            isDefault = true
        }

        if (!style || style == 'primary') {

            if (!data) throw new Error('数据格式不正确')

            var checked = 'layui-form-checked'
            var str =
                '      <div class="layui-unselect layui-form-checkbox" lay-skin="' + style + '">' +
                '        <input type="hidden" />' +
                '        <span></span>' +
                '        <i class="layui-icon"></i>' +
                '     </div>'


            for (var i = 0; i < data.length; i++) {
                var ele = data[i]

                if (value && $.inArray('on', value) != -1 && ele.value == value) {
                    isDefault = false
                }

                var $str = $(str)

                $str.find('input').val(ele.value).attr('name', name)
                $str.find('span').html(ele.title)

                $str.on('click', function () {

                    var values = $this.value ? $this.value : $this.value = new Array()

                    if ($(this).hasClass(checked)) {

                        var val = $(this).removeClass(checked).find('input').val()

                        for (var i = 0; i < values.length; i++) {
                            if (values[i] == val) {
                                values.splice(i, 1)
                            }
                        }

                    } else {
                        var val = $(this).addClass(checked).find('input').val()
                        values.push(val)
                    }

                    var strVal = ''
                    for (var j = 0; j < values.length; j++) {
                        strVal += ',' + values[j]
                    }

                    strVal = strVal ? strVal.substring(1) : strVal

                    $this.$element[0].value = strVal
                })

                if ($.inArray(ele.value + '', value) != -1) {
                    $str.trigger('click')
                }
                this.$element.after($str)
                var selects = this.selects ? this.selects : this.selects = new Array()
                selects.push($str)
            }

        } else if (style == 'switch') {

            this.$element.prop('checked', 'checked')

            if (value.length > 1) return

            var checked = 'layui-form-onswitch'

            var str = '<div class="layui-unselect layui-form-switch" lay-skin="_switch">' +
                '        <input type="hidden"/>' +
                '        <em>OFF</em>' +
                '        <i></i>' +
                '    </div>'


            var $str = $(str)

            this.$select = $str

            var arr = new Array()

            if (data == null || data == undefined) {

                $str.find('input').val(false)
                this.$element.val(false)
                $str.find('em').html('OFF')
                this.$element.after($str)
                arr = [{value: false, title: 'OFF'}, {value: true, title: 'ON'}]

            } else {
                if (data.length != 2) {
                    alert('复选框数据格式不正确')
                    throw new Error('复选框数据格式不正确')
                }

                var arr = new Array()

                for (var i = 0; i < data.length; i++) {
                    var ele = data[i]

                    if (value && value == 'on' && value == ele.value) {
                        isDefault = false
                    }
                    if (i == 0) {
                        $str.find('input').val(ele.value + '')
                        this.$element.val(ele.value + '')
                        $str.find('em').html(ele.title)
                        this.$element.after($str)

                        if (ele.value == true) {
                            $str.addClass('layui-form-onswitch')
                        }

                    }

                    arr.push(ele)
                }
            }

            this.$select.data('data', arr)


            //点击事件
            this.$select.on('click', function () {
                var sdata = $(this).data('data')

                if (!sdata) return

                var val = $(this).find('input').val()


                var checkEle = null

                for (var j = 0; j < sdata.length; j++) {
                    if (sdata[j].value + '' != val) {
                        checkEle = sdata[j]
                    }
                }

                if (!checkEle) return

                if (checkEle.value == true) {
                    $(this).addClass('layui-form-onswitch')
                } else {
                    if ($(this).hasClass('layui-form-onswitch')) {
                        $(this).removeClass('layui-form-onswitch')
                    } else {
                        $(this).addClass('layui-form-onswitch')
                    }
                }

                $(this).find('input').val(checkEle.value)

                $this.$element[0].value = checkEle.value

                $(this).find('em').html(checkEle.title)

            })

            if (isDefault) value = ''

            if (value) {
                if (this.$select.find('input').val() + '' != value + '') {
                    this.$select.trigger('click')
                }
            }
        }


        this.parseOver = true
    }

    //初始化单选框
    PtyxeleForm.prototype.initRadio = function () {

        var $this = this
        this.$element.prop('checked', 'checked')
        var value = this.$element.val()
        var data = this.$element.data('value')

        var str = '<div class="layui-unselect layui-form-radio">' +
            '        <i class="layui-anim layui-icon"></i>' +
            '        <div>男</div>' +
            '    </div>'
        var checked = 'layui-form-radioed'
        var iChecked = 'layui-anim-scaleSpring'


        if (data) {
            data = Ptyxele.UTIL.parseQuickAttrValueObj(data)
        }

        if (!data) {
            alert('数据格式不正确')
            throw new Error('数据格式不正确')
        }

        var $checked = null

        for (var i = 0; i < data.length; i++) {
            var $str = $(str)

            $str.data('value', data[i].value + '')

            $str.find('div').html(data[i].title)

            if (data[i].value + '' == value) {
                $checked = $str
            }

            this.$element.after($str)

            var selects = this.selects

            if (!selects) {
                this.selects = new Array()
                selects = this.selects
            }

            selects.push($str)

            $str.on('click', function () {
                $this.$checked = $(this)
                for (var j = 0; j < $this.selects.length; j++) {
                    var $ele = $this.selects[j]
                    $ele.removeClass(checked)
                    $ele.find('i').removeClass(iChecked)
                }
                $(this).addClass(checked).find('i').addClass(iChecked)

                $this.$element[0].value = $(this).data('value')

                var val = $(this).data('value')

                $this.$element.trigger('event.form.checked.ptyxele-api', val)
            })

        }

        if ($checked) {
            this.$checked = $checked
            $checked.trigger('click')
        }

        this.parseOver = true
    }

    //表单的回写
    PtyxeleForm.prototype.echoForm = function (data) {

        if (!data || !(data instanceof Object)) return

        var provinceObj = new Object()

        var moduleArr = new Array()

        var commonArr = new Array()

        for (name in data) {

            var $ele = this.$element.find('[name="' + name + '"]')


            var edata = $ele.data(Ptyxele.PTYXELE)

            if (edata && edata.module) {
                if (/^(?:city|area|province)/i.test(edata.module)) {
                    provinceObj[edata.module] = {object: $ele, value: data[name]}
                } else {
                    moduleArr.push({object: $ele, value: data[name]})
                }
                continue
            }

            if ($ele.length == 0 || !/^(?:select|textarea|input)/i.test($ele[0].tagName)) continue

            var fdata = $ele.data(PtyxeleForm.PACE)

            if (fdata) {
                moduleArr.push({object: $ele, value: data[name]})
                continue
            }

            commonArr.push({object: $ele, value: data[name]})
        }

        //处理省市区组件回写
        if (!provinceObj.city && provinceObj.area) {
            var $ele = provinceObj.area.object
            var parentid = $ele.ptyxProvinceParentId()
            if (parentid) {
                throw  new Error('省市区数据初始化，顺序不一致')
            }
        }


        if (!provinceObj.province && provinceObj.city) {
            var $ele = provinceObj.city.object
            var parentid = $ele.ptyxProvinceParentId()
            if (parentid) {
                throw  new Error('省市区数据初始化，顺序不一致')
            }
        }

        var proArr = ['province', 'city', 'area']

        for (var i = 0; i < proArr.length; i++) {
            var pro = provinceObj[proArr[i]]
            if (pro) {
                pro.object.val(pro.value)
            }
        }


        //组件赋值
        for (var i = 0; i < moduleArr.length; i++) {
            var ele = moduleArr[i]
            ele.object.val(ele.value)
        }

        //普通input，select,textarea初始化
        for (var i = 0; i < commonArr.length; i++) {
            var obj = commonArr[i]

            var val = obj.value

            var $element = obj.object

            for (var j = 0; j < obj.object.length; j++) {

                var $ele = $(obj.object[j]).eq(0)
                var type = $ele.attr('type')
                var tagName = $ele[0].tagName

                if (tagName == 'INPUT') {

                    if (type == 'radio') {
                        if ($ele.next().length == 0 || $ele.next()[0].tagName != 'INS') {
                            $element.iCheck({
                                checkboxClass: 'icheckbox_minimal-green',
                                radioClass: 'iradio_minimal-green'
                            });
                        }
                        if ($ele.val() == val) {
                            $ele.iCheck('check')
                            $ele.prop("checked", "checked")
                        }
                    } else if (type == 'checkbox') {
                        if ($ele.next().length == 0 || $ele.next()[0].tagName != 'INS') {

                            $element.iCheck({
                                checkboxClass: 'icheckbox_minimal-green',
                                radioClass: 'iradio_minimal-green'
                            })
                        }
                        var values = new Object()
                        if (val && val.indexOf(',') != -1) {
                            var arr = obj.value.split(',')
                            for (var z = 0; z < arr.length; z++) {
                                values[arr[z]] = arr[z]
                            }
                        } else {
                            values[obj.value] = obj.value
                        }
                        if (values[$ele.val()]) {
                            $ele.iCheck('check')
                            $ele.prop("checked", "checked")
                        }

                    } else if ($ele.attr('data-fload')) {//如果是上传图片插件

                        $ele.fval(val)

                    } else if (val && val.time) {//如果时间 格式化时间
                        var date = new Date(val.time)
                        var format = $ele.attr('data-form')
                        if (format) {
                            if (format == 'yyyy-MM-dd hh:mm:ss') {
                                $ele.val(date.format('yyyy-MM-dd hh:mm:ss'))
                            } else {
                                $ele.val(date.format('yyyy-MM-dd'))
                            }
                        } else {
                            $ele.val(date.format('yyyy-MM-dd'))
                        }
                    } else {
                        var val = val ? val + '' : '';
                        if (val.indexOf('<') != -1 || val.indexOf('>') != -1) {
                            $ele.val('')
                        } else if (val.trim() == 'null') {
                            $ele.val('')
                        } else {
                            $ele.val(val)
                        }
                    }
                } else if (tagName == 'SELECT') {

                    var $objSelet = $ele.find('option[value="' + val + '"]')

                    if ($objSelet.length == 0 && (val == true || val == false)) {
                        var seleVal = val == true ? 1 : 0
                        $objSelet = $ele.find('option[value="' + seleVal + '"]')
                    }
                    $objSelet.prop('selected', true)
                    $ele.trigger('change')
                } else if (tagName == 'TEXTAREA') {
                    if ($ele.hasClass('is-summernode')) {
                        $ele.summernote('code', val)
                    } else {
                        $ele.val(val)
                    }
                } else if (tagName == 'SPAN') {
                    $ele.html(val)
                }
            }
        }


    }

    //数据验证
    PtyxeleForm.prototype.verifyData = function () {

    }


    //重写值
    PtyxeleForm.prototype.val = function (value) {

        var tagName = this.$element[0].tagName

        if (value == undefined || value == null) {

            if (tagName == 'INPUT') {
                var type = this.$element.attr('type')

                if (type == 'checkbox') {

                    var skin = this.$element.attr('lay-skin')

                    if (skin == 'switch') {
                        return this.$select.find('input').val()
                    } else {

                        var inputVal = ''

                        for (var i = 0; i < this.selects.length; i++) {

                            var $select = this.selects[i]

                            if ($select.hasClass('layui-form-checked')) {
                                var v = $select.find('input').val()
                                inputVal += ',' + v
                            }
                        }

                        if (inputVal) {
                            inputVal = inputVal.substring(1)
                        }
                        return inputVal
                    }
                } else if (type == 'radio') {

                    return this.$checked ? this.$checked.data('value') : ''
                }
            } else if (tagName == 'SELECT') {
                return this.$select.find('input[type="hidden"]').val()
            }
        } else {

            var values = new Array()

            if (typeof  value == 'string') {
                values = value.split(',')
            } else if (typeof value == 'number' || typeof  value == 'boolean') {
                values.push(value + '')
            } else if (value instanceof Array) {
                values = value
            }


            if (tagName == 'INPUT') {

                var type = this.$element.attr('type')

                if (type == 'checkbox') {

                    var skin = this.$element.attr('lay-skin')

                    if (skin == 'switch') {

                        var oval = this.$select.find('input').val()

                        var sdata = this.$select.data('data')

                        if ($.inArray(oval, values) == -1) {
                            this.$select.trigger('click')
                        }

                    } else {

                        var checked = 'layui-form-checked'

                        for (var i = 0; i < this.selects.length; i++) {

                            var $select = this.selects[i]

                            var sval = $select.find('input').val()

                            if ($.inArray(sval, values) != -1) {

                                if (!$select.hasClass(checked)) {
                                    $select.trigger('click')
                                }

                            } else {
                                if ($select.hasClass(checked)) {
                                    $select.trigger('click')
                                }
                            }
                        }
                    }
                } else if (type == 'radio') {
                    for (var i = 0; i < this.selects.length; i++) {
                        var $ele = this.selects[i]
                        if (value + '' == $ele.data('value')) {
                            this.$checked = $ele
                            $ele.trigger('click')
                            continue
                        }
                    }
                }

            } else if (tagName == 'SELECT') {

                if (values.length > 1) return

                var $dd = this.$select.find('dd[lay-value="' + values[0] + '"]')

                $dd.trigger('click')
            }

            return this.$element
        }
    }

    function Plugin() {
        return this.each(function () {

            var $this = $(this)

            var data = $this.data(PtyxeleForm.PACE)

            if (!data) {
                $this.data(PtyxeleForm.PACE, (data = new PtyxeleForm(this)))
                data.initForm()
            }
        })
    }

    function Submit(data, fn) {
        var $this = $(this)
        var data = $this.data(Ptyxele.PACE)


        if (!data || (data && !data.ptyxele) || (data && data.ptyxele && data.ptyxele.module != 'form')) {
            return oldSubmit.call($this, data, fn)
        } else {
            var fdata = $this.data(PtyxeleForm.PACE)
            return fdata.submit(data, fn)
        }
    }

    function ParseFormNode() {

        var $this = $(this)

        if (IsPtyxFormEle($(this))) {
            var data = $this.data(PtyxeleForm.PACE)
            if (!data) {
                $this.data(PtyxeleForm.PACE, (data = new PtyxeleForm(this)))
            }
            data.init()
        }
    }

    function IsPtyxFormEle(self) {
        var $ele = $(self)

        var $form = $ele.closest('form')

        if ($form.length == 0) return false

        if ($form.attr('ptyx-form') == undefined) return false

        var attributes = $ele[0].attributes
        $.each(attributes,function (k, v) {
            if (/^ptyx-{1}.*$/.test(v.name)) {
                return false
            }
        })

        var tagName = $ele[0].tagName

        var initTagert = ['checkbox', 'radio']

        if (tagName == 'INPUT') {

            var type = $ele.attr('type')

            if ($.inArray(type, initTagert) != -1) {
                return true
            }

        } else if (tagName == 'SELECT') {
            return true
        }

        return false
    }

    function FormEleValue(value) {

        var $this = $(this)

        if (IsPtyxFormEle($(this))) {

            var data = $this.data(PtyxeleForm.PACE)
            if (data) {

                if (!data.parseOver) {
                    return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
                }

                return data.val(value)
            } else {
                return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
            }
        } else {

            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }
    }

    function SerializeArray() {

        var $this = $(this)
        var data = $this.data(Ptyxele.PACE)

        if (!data || data.ptyxele.module != 'form') {
            return oldSerializeArray.call($this)
        } else {
            var fdata = $this.data(PtyxeleForm.PACE)
            return fdata.serializeArray()
        }
    }


    function Serialize() {
        var $this = $(this)
        var data = $this.data(Ptyxele.PACE)

        if (!data || data.ptyxele.module != 'form') {
            return oldSerialize.call($this)
        } else {
            var fdata = $this.data(PtyxeleForm.PACE)
            return fdata.serialize()
        }
    }

    //表单的回写
    function EchoForm(data) {
        var $this = this

        if ($this[0].tagName != 'FORM') return $this

        var fdata = $this.data(PtyxeleForm.PACE)
        if (!fdata) {
            $this.data(PtyxeleForm.PACE, (fdata = new PtyxeleForm(this)))
        }
        fdata.init()
        return fdata.echoForm(data)
    }

    //下来框动态添加值
    function AddPtyxSelectOption(data,colKey,valKey) {
        var $this = this
        if ($this[0].tagName != 'SELECT') return $this
        var fdata = $this.data(PtyxeleForm.PACE)
        if (fdata) {

            var selected = 'layui-form-selected'

            var $dl = fdata.$select.find('dl')
            for (var i = 0; i < data.length; i++) {
                var option = data[i]
                var $dd = $(`<dd lay-value="${option[colKey ? colKey:'value']}">${option[valKey ? valKey:'name']}</dd>`)
                $dl.append($dd)

                $dd.on('click', function () {

                    var oldVal = fdata.$element.val()

                    var val = $(this).attr('lay-value')

                    $(this).closest('dl').find('.layui-this').removeClass('layui-this')

                    fdata.$select.find('.layui-input').attr('placeholder', $(this).text())

                    if (val) {
                        $(this).addClass('layui-this')
                        fdata.$select.find('input[type="hidden"]').val(val)
                    } else {
                        fdata.$select.find('input[type="hidden"]').val('')
                    }

                    fdata.$element.find('option[value="' + val + '"]').prop('selected', true)


                    var currVal = fdata.$element.val()

                    fdata.$select.removeClass(selected)

                    //值不一样触发change事件
                    if(oldVal != currVal) {
                        fdata.$element.trigger('change')
                    }
                })

            }
        }
    }


    // var oldSubmit = $.fn.submit

    var oldVal = $.fn.val

    // var oldSerializeArray = $.fn.serializeArray

    // var oldSerialize = $.fn.serialize

    $.fn.ptyxeleForm = Plugin

    // $.fn.submit = Submit

    // $.fn.serializeArray = SerializeArray

    // $.fn.serialize = Serialize

    $.fn.ptyxeleFormNode = ParseFormNode

    $.fn.val = FormEleValue

    $.fn.echo = EchoForm

    $.fn.ptyxAddSelOption = AddPtyxSelectOption

    $(window).on('load', function () {
        $('[ptyx-form],[ptyx-data*="module:form"]').each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxeleForm()
        })

        $('[ptyx-form],[ptyx-data*="module:form"]').find('select').each(function () {
            $(this).ptyxeleFormNode()
        })
    })


    $(document).on('create.form.ptyxele-api', 'input,select', function () {

        $(this).ptyxeleFormNode()
    })


}(jQuery);

/**
 * Created by chenzp on 18-3-17.
 */
+function ($) {

    var PtyxeleLoad = function (ele, option) {
        this.$element = $(ele)

        this.options = $.extend({}, PtyxeleLoad.DEFAULT, option)
        this.init()
    }

    PtyxeleLoad.PACE = 'ptyx.load'

    PtyxeleLoad.DEFAULT = {
        module: 'load'
        /**
         * 上传文件提示语
         */
        , placeholder: '上传文件'
        /**
         * 文件格式  图片格式：img，视频格式：video，其他的格式可以自定义
         * 默认是img
         */
        , accept: 'image'
        /**
         * 是否支持批量上传  默认为可批量上传
         */
        , batch: true
        /**
         * 文件大小，对单个文件大小限定 单位为b
         * 默认为10485760  10m
         */
        , size: 10485760
        // , size: 10000
        /**
         * 上传文件数量限定
         */
        , maxNum: 10
        /**
         * 上传最小文件数
         */
        , minNUm: 1
        /**
         * 是否显示进度条
         */
        , progress: false
        /**
         * XMLHttpRequest上传配置参数
         */
        , HttpRequestOption: {
            cache: false,
            file: 'files'
        }
        /**
         * 上传文件成功回调函数
         */
        , callback: null
        /**
         * 阿里云图片压缩参数
         */
        , ossParams: '1e_100w_100h_1c_0i_90Q_1x'


    }

    PtyxeleLoad.prototype.init = function () {

        this.$element.hide()

        this.mergeOption()
        this.createModel()

        if (this.options.value) {
            this.val(this.options.value)
        }
    }

    //初始化事件
    PtyxeleLoad.prototype.initEvent = function () {

    }

    //创建模块
    PtyxeleLoad.prototype.createModel = function () {
        var opt = this.options

        var $str = $('<div class="ptcs-load">' +
            '<div class="layui_upload">' +
            '        <button type="button" class="layui_btn"><i class="layui-icon"></i></button>' +
            '        <input class="layui_upload_file" type="file" >' +
            '</div>' +
            '</div>')


        if (opt.placeholder) {
            var title = opt.placeholder

            if (title.length > 4) {
                title = opt.placeholder.substring(0, 4)
            }
            $str.find('button>i').after(title)
            $str.find('.layui_upload').attr('title', title)
        }

        if (opt.readonly) {
            $str.find('.layui_upload').hide()
        }

        this.$element.after($str)

        this.$load = $str

        this.$upload = $str.find('input')

        if (opt.batch) {
            this.$upload.attr('multiple', 'multiple')
        }

        this.$upload.on('change', $.proxy(this.uploadFileEvent, this));//上传文件
    }

    //创建预览图
    PtyxeleLoad.prototype.createView = function () {
        var $str = $('<div class="ptcs-load-view">' +
            '        <div class="ptcs-load-view-close"><i>×</i></div>' +
            '        <div class="ptcs-load-view-main">' +
            '         </div>' +
            '        <div class="ptcs-load-view-thumb">' +
            '            <div class="ptcs-load-view-thumb-area">' +
            '            </div>' +
            '        </div>' +
            '        <div class="ptcs-load-view-zoom-pro"><span class="hidden" style="display: none;"></span></div>' +
            '    </div>')

        var opt = this.options
        var $this = this
        $this.$load.append($str)
        $this.$veiw = $str
        $this.$vMain = $str.find('.ptcs-load-view-main')
        $this.$vThumb = $str.find('.ptcs-load-view-thumb')
        $this.$vArea = $str.find('.ptcs-load-view-thumb-area')


        //关闭预览区
        $str.find('.ptcs-load-view-close').on('click', function () {
            $this.$veiw.removeClass('active')
            $('body').css('overflow', '').scrollTop(0)
        })
    }

    //打开预览区
    PtyxeleLoad.prototype.showView = function () {

        if (!this.$veiw) {
            this.createView()
        }

        $('body').css({'overflow': 'hidden'})
        $(document).scrollTop(0)

        this.$veiw.addClass('active')
    }

    //加载图片
    PtyxeleLoad.prototype.loadImgToVeiw = function (key) {
        var $list = this.$load.find('.layui_upload_list')

        if ($list.length == 0) return


        var $area = this.$vArea
        var $main = this.$vMain


        $area.find('img').remove()
        $main.find('img').remove()

        var $activeImg = null, activeData = null

        for (var i = 0; i < $list.length; i++) {
            var $ele = $list.eq(i)
            var elekey = $ele.data('data')
            var ele = this.store[elekey]

            if (!ele.isImg) continue

            var $img = $('<img/>')

            $area.append($img)

            $img.data('data', elekey)

            //点击切换图片
            $img.on('click', $.proxy(this.switchThumbImgEvent, this))

            if (!ele.file) {

                $img.attr('src', ele.thumbUrl).attr('title', ele.fileName)

            } else {
                this.toBase64Img($img, ele.file)
            }

            if ($main.find('img').length == 0) {
                if (key) {
                    if (elekey == key) {
                        $img.addClass('active')
                        $activeImg = $img
                        activeData = ele
                    }
                } else {
                    $img.addClass('active')
                    $activeImg = $img
                    activeData = ele
                }
            }

        }

        var opt = this.options
        var $this = this

        //预览区主显示区
        if ($activeImg) {

            var $mainImg = $('<img ondragstart="return false;"/>')

            $main.append($mainImg)

            //旋转图片
            $mainImg.on('click', $.proxy(this.viewRateImgEvent, this))

            //放大缩放图片
            $mainImg.on('mousewheel', $.proxy(this.scrollViewImgEvent, this))

            //图片拖拽
            $mainImg.on('mousedown mousemove mouseup', $.proxy(this.dragViewImgEvent, this))

            $mainImg.on('load', $.proxy(this.autoAdaptiveEvent, this))


            if (!activeData.file) {

                if (activeData.url) {
                    $mainImg.attr('src', activeData.url)
                    return
                }

                $.ajax({
                    url: opt.url
                    , data: {key: activeData.key}
                    , dataType: 'json'
                    , type: 'GET'
                    , success: function (res) {

                        if (!res.successful) {
                            if (res.msg) {
                                throw new Error(res.msg)
                            }
                            throw new Error('数据请求失败')
                        } else {
                            if (res.result) {
                                $this.addStore(activeData.key, {url: res.result.url})
                                $mainImg.attr('src', res.result.url)
                            }
                        }
                    }
                    , error: function (e) {
                        throw (e)
                    }
                })

            } else {
                this.toBase64Img($mainImg, activeData.file)
            }

        }

    }

    //file转base64图片
    PtyxeleLoad.prototype.toBase64Img = function ($img, file) {
        //判断是否支持FileReader
        if (window.FileReader) {
            var reader = new FileReader()
        } else {
            alert('提示', '您的设备不支持图片预览功能，如需该功能请升级您的设备！')
            return
        }

        //读取完成
        reader.onload = function (e) {
            $img.attr('src', e.target.result)
        }
        reader.readAsDataURL(file)
    }

    //上传文件
    PtyxeleLoad.prototype.upLoadFile = function (file) {

        var opt = this.options
        var $this = this

        var fd = new FormData() //FormData对象

        var fileName = opt.HttpRequestOption.file

        fd.append(fileName, file)

        if (opt.HttpRequestOption.cache) {
            fd.append("acttime", new Date().toString())
        }

        var xhr = new XMLHttpRequest()//创建xhr

        xhr.open("POST", opt.url, true)

        xhr.onreadystatechange = function (resfile) {

            try {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = xhr.responseText

                    if (opt.callback && typeof opt.callback == 'function') {
                        var res = opt.callback(result)
                        if (res) {
                        }
                    } else {
                        var jsonObj = JSON.parse(result)
                        if (jsonObj.successful) {

                            var res = jsonObj.result

                            var valKey = ''
                            var fileUrl = ''
                            for (val in res) {
                                $this.addValue(val)
                                valKey = val
                                fileUrl = res[val]
                            }

                            $this.addStore(valKey, {file: file})

                            $this.drawFile(file, valKey,fileUrl)
                        } else {
                            throw new Error('上传失败--' + '信息：' + '' + jsonObj.message)
                        }
                    }

                } else if (xhr.readyState == 4 && xhr.status != 200) {
                    alert('上传文件失败')
                    throw new Error('上传文件失败')
                }
            } catch (e) {
                alert(e)
                throw new Error(e)
            }
        }

        // xhr.upload.onprogress = function (evt) {//进度条部分
        //     try {
        //
        //         console.info(evt);
        //         // var percentComplete = Math.round(evt.loaded * 100 / evt.total);
        //
        //     } catch (e) {
        //         throw new Error(e)
        //     }
        // }
        xhr.send(fd)
    }

    //文件大小验证
    PtyxeleLoad.prototype.validateFileSize = function (size, isProp) {
        var opt = this.options

        if (!size) return false

        if (size > opt.size) {
            isProp ? alert('上传文件大小' + parseInt(size / 1024) + 'KB,超过限定' + parseInt(opt.size / 1024) + 'KB') : ''
            return false
        }

        return true
    }

    //文件格式的验证
    PtyxeleLoad.prototype.validateFileFormat = function (format, isProp) {

        if (format.length == 0) {

            isProp ? alert('文件格式不正确') : ''
            return false
        }

        var opt = this.options
        format = format.toLowerCase()

        var accept = opt.accept

        if (accept == 'image') {
            var reg = /(^png{1}$)|(^jpeg{1}$)|(^gif{1}$)|(^jpg{1}$)|(^bmp{1}$)/

            if (!reg.test(format)) {
                isProp ? alert('上传文件不是图片') : ''
                return false
            }

        } else if (accept == 'video') {
            var reg = /(^wmv{1}$)|(^3gp{1}$)|(^mp4{1}$)|(^mov{1}$)|(^avi{1}$)|(^flv{1}$)|(^mkv{1}$)|(^rmvb{1}$)/

            if (!reg.test(format)) {
                isProp ? alert('上传文件不是视频') : ''
                return false
            }
        } else if (accept == 'attachment') {
            var reg = /(^pdf{1}$)|(^doc{1}$)|(^docx{1}$)|(^xls{1}$)|(^xlsx{1}$)|(^txt{1}$)|(^png{1}$)|(^jpeg{1}$)|(^gif{1}$)|(^jpg{1}$)|(^bmp{1}$)|(^rar{1}$)|(^zip{1}$)|(^ppt{1}$)|(^pdf{1}$)/
            if (!reg.test(format)) {
                isProp ? alert('上传文件不是规定的格式') : ''
                return false
            }
        } else {
            if (format != accept) {
                isProp ? alert('上传文件格式不正确') : ''
                return false
            }
        }

        return true
    }

    //获取文件格式
    PtyxeleLoad.prototype.getFormat = function (name) {

        if (!name) return false

        if (typeof  name != 'string') return false

        //去空
        name = name.replace(/^\s*|\s*$/g, "")

        if (name.length < 2) return false

        var index = name.lastIndexOf('.')

        return name.substring(index + 1)
    }

    //渲染文件缩略图
    PtyxeleLoad.prototype.drawFile = function (file, valKey,url) {

        var format = ''

        var fileName = ''

        if (file instanceof File) {
            fileName = file.name
            format = this.getFormat(fileName)
        } else {
            fileName = file.info['Content-Disposition'].split(';')[1].split('=')[1]
            format = this.getFormat(fileName)
        }

        //判断是否是图片

        var reg = /(^png{1}$)|(^jpeg{1}$)|(^gif{1}$)|(^jpg{1}$)|(^bmp{1}$)/

        var stat = false

        if (reg.test(format)) {
            stat = true
        }

        var $str = $('<div class="layui_upload_list">' +
            '            <img class="layui-upload-img">' +
            '            <a class="ptcs-load-delete">删除</a>' +
            '       </div>')


        var opt = this.options

        if (opt.readonly) {
            $str.find('.ptcs-load-delete').remove()
        }

        //存储数据
        this.addStore(valKey, {fileName: fileName, isImg: stat})
        $str.data('data', valKey)

        //删除按钮浮动显示
        // $str.on('hover', $.proxy(this.showDelBtnEvent, this))

        var $this = this
        $str.hover(function (e) {


            var $target = $(e.currentTarget)

            var type = e.type

            var $del = $target.find('.ptcs-load-delete')

            if ($del.length == 0) return

            type == 'mouseenter' ? $del.show() : $del.hide()

        },function (e) {

            var $target = $(e.currentTarget)

            var type = e.type

            var $del = $target.find('.ptcs-load-delete')

            if ($del.length == 0) return

            type == 'mouseenter' ? $del.show() : $del.hide()
        })


        //删除文件
        $str.find('a').on('click', $.proxy(this.deleteFileEvent, this))

        //下载文件
        $str.on('click', $.proxy(this.downloadFile, this))


        this.$load.prepend($str)
        //非图片
        if (!stat) {

            var className = 'ptcs-load-' + format
            $str.find('img').addClass(className)
            $str.attr('title', fileName)

            if (!(file instanceof File)) {
                var $a = $('<a target="_blank"></a>')
                $a.attr('href', file.url)
                $str.find('img').after($a)
            }else{
                var $a = $('<a target="_blank"></a>')
                $a.attr('href', url ? url:'')
                $str.find('img').after($a)
            }
            return
        }

        //是图片
        if (!(file instanceof File)) {

            $str.find('img').attr('src', file.url).attr('title', fileName)

        } else {
            this.toBase64Img($str.find('img'), file)
        }
        return
    }

    //根据KEY获取阿里云文件
    PtyxeleLoad.prototype.addFileByOssKey = function (key, param) {
        var $this = this
        var opt = this.options
        var dataParam = new Object()

        if (param && typeof param != 'undefined') {
            dataParam = {key: key, param: param}
        } else {
            dataParam = {key: key}
        }

        if (!opt.url) {
            alert('上传地址不能为空')
            throw new Error('上传地址不能为空')
        }

        $.ajax({
            url: opt.url
            , data: dataParam
            , dataType: 'json'
            , type: 'GET'
            , success: function (res) {

                if (!res.successful) {
                    if (res.msg) {
                        throw new Error(res.msg)
                    }
                    throw new Error('数据请求失败')
                } else {
                    if (res.result) {

                        $this.addStore(key, {info: res.result.info, thumbUrl: res.result.url})

                        $this.drawFile(res.result, key,res.result.url)
                    }
                }
            }
            , error: function (e) {
                throw (e)
            }
        })
    }

    //保存数据
    PtyxeleLoad.prototype.addStore = function (key, data) {

        if (!key) return

        if (!this.store) {
            this.store = {}
        }

        var store = this.store

        if (!store[key]) {

            store[key] = $.extend({}, {key: key}, data)

        } else {
            store[key] = $.extend({}, {key: key}, store[key], data)
        }
    }

    //下载文件或预览图片
    PtyxeleLoad.prototype.downloadFile = function (e) {
        var $target = $(e.currentTarget)

        var key = $target.data('data')

        var ele = this.store[key]

        if (ele.isImg) {
            this.showView()
            this.loadImgToVeiw(key)
        } else {
            var href = $target.find('a:eq(0)').attr('href')
            window.open(href)
        }
    }

    //事件-变化-上传文件
    PtyxeleLoad.prototype.uploadFileEvent = function (e) {
        var $target = $(e.target)
        var opt = this.options
        var files = e.currentTarget.files

        if (files.length == 0) {
            throw new Error('上传文件不能发为空')
        }

        var stat = true

        for (var i = 0; i < files.length; i++) {

            var file = files[i]

            if (!this.validateFileSize(file.size, true)) {
                stat = false
                break
            }

            var format = this.getFormat(file.name)

            if (!format) break

            if (!this.validateFileFormat(format, true)) {
                stat = false
                break
            }
        }

        if (!stat) return


        var fileNum = this.fileNum

        if (!fileNum) {
            this.fileNum = 0
            fileNum = 0
        }

        if (opt.maxNum < fileNum + files.length) {
            alert('上传文件数量超出限定')
            return
        }

        for (var i = 0; i < files.length; i++) {
            var file = files[i]
            this.upLoadFile(file)
        }

        var $newFileInput = $target.clone().val('')
        $target.after($newFileInput)
        $target.remove()
        $newFileInput.on('change', $.proxy(this.uploadFileEvent, this))

    }

    //事件-删除文件
    PtyxeleLoad.prototype.deleteFileEvent = function (e) {
        var $target = $(e.currentTarget)
        var $parent = $target.closest('.layui_upload_list')
        var key = $parent.data('data')

        if (!key) return

        this.delValue(key)
        $parent.remove()
    }

    //显示删除按钮
    PtyxeleLoad.prototype.showDelBtnEvent = function (e) {

        var $target = $(e.currentTarget)

        var type = e.type

        var $del = $target.find('.ptcs-load-delete')

        if ($del.length == 0) return

        type == 'mouseenter' ? $del.show() : $del.hide()
    }

    //预览区，图片切换
    PtyxeleLoad.prototype.switchThumbImgEvent = function (e) {
        var $target = $(e.currentTarget)
        var key = $target.data('data')
        var ele = this.store[key]
        var opt = this.options
        var $this = this

        var $thumb = this.$vThumb
        var $main = this.$vMain

        $thumb.find('img.active').removeClass('active')

        $target.addClass('active')

        $main.empty()

        var $img = $('<img ondragstart="return false;"/>')
        //旋转图片
        $img.on('click', $.proxy(this.viewRateImgEvent, this))

        //放大缩放图片
        $img.on('mousewheel', $.proxy(this.scrollViewImgEvent, this))

        $img.on('load', $.proxy(this.autoAdaptiveEvent, this))

        //图片拖拽
        $img.on('mousedown mousemove mouseup', $.proxy(this.dragViewImgEvent, this))


        $main.append($img)

        if (!ele.file) {

            var url = ele.url

            if (url) {
                $img.attr('src', url)
                return
            }


            $.ajax({
                url: opt.url
                , data: {key: key}
                , dataType: 'json'
                , type: 'GET'
                , success: function (res) {

                    if (!res.successful) {
                        if (res.msg) {
                            throw new Error(res.msg)
                        }
                        throw new Error('数据请求失败')
                    } else {
                        if (res.result) {
                            $this.addStore(key, {url: res.result.url})
                            $img.attr('src', res.result.url)
                        }
                    }
                }
                , error: function (e) {
                    throw (e)
                }
            })

        } else {
            this.toBase64Img($img, ele.file)
        }
    }

    //点击-旋转图片
    PtyxeleLoad.prototype.viewRateImgEvent = function (e) {
        var $target = $(e.currentTarget);
        var cls = 'ptcs-load-view-rotate';
        var data = $target.data('rotate');
        if (!data) {
            $target.removeClass(cls).addClass(cls + '-90').data('rotate', 90);
        } else {
            var r = parseInt(data);
            var m = r + 90 == 360 ? '' : r + 90;
            var s = m == '' ? cls + '' : cls + '-' + m;
            var n = r == '' ? cls + '' : cls + '-' + r;
            $target.data('rotate', m).removeClass(n).addClass(s);
        }

        var offset = $target.offset()

        // $target.parent().css({top:offset.top,left:offset.left})
        $target.data('drag', null)
    }

    //滚动-放大与缩放图片
    PtyxeleLoad.prototype.scrollViewImgEvent = function (e) {

        var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;//firefox使用detail:下3上-3,其他浏览器使用wheelDelta:下-120上120//下滚


        var isDown = delta > 0 ? true : false


        var se = e.originalEvent

        var pX = se.pageX
        var pY = se.pageY
        var $target = $(e.currentTarget)
        var top = $target.parent().offset().top
        var left = $target.parent().offset().left


        var multiple = $target.data('multiple')

        if (!multiple) {
            multiple = 100
        }

        var height = $target.outerHeight()

        var changVal = 0.03

        if (isDown) {//缩放

            $target.css('height', height * (1 - changVal))

            $target.parent().css({top: (top + (pY - top) * changVal), left: ((pX - left) * changVal + left)})

            multiple = multiple - 3

        } else {//放大

            $target.css('height', height * (1 + changVal))

            $target.parent().css({top: (top - (pY - top) * changVal), left: (left - (pX - left) * changVal)})
            multiple = multiple + 3
        }

        $target.data('multiple', multiple)


        var $percent = this.$veiw.find('.ptcs-load-view-zoom-pro>span')
        $percent.show().html(multiple + '%')

        if (this.timer) {
            clearTimeout(this.timer)
        }

        this.timer = setTimeout(function () {
            $percent.hide()
        }, 2000)

    }

    //图片自动响应预览区
    PtyxeleLoad.prototype.autoAdaptiveEvent = function (e) {
        var $target = $(e.currentTarget)

        var wH = window.innerHeight

        var wW = window.innerWidth

        var iH = $target.outerHeight()
        var iW = $target.outerWidth()

        var tH = this.$vThumb.outerHeight()

        var $parent = $target.parent()

        if (wH - tH < iH) {

            $target.css({height: (wH - tH) - 10})

            $parent.css('top', 5)

        } else {
            // $target.css({'margin-top':((wH - tH) - iH)/2})

            $parent.css('top', ((wH - tH) - iH) / 2)
        }
        iW=$target.outerWidth();
        if (wW < iW) {
            $parent.css('left', 0)
        } else {
            $parent.css('left', ((wW - iW) / 2))
        }

    }

    //拖动图片
    PtyxeleLoad.prototype.dragViewImgEvent = function (e) {
        var type = e.type

        var $target = $(e.currentTarget)

        if (type == 'mousemove') {
            var drag = $target.data('drag')

            if (!drag) return

            var se = e.originalEvent
            var $parent = $target.parent()
            var top = $target.parent().offset().top
            var left = $target.parent().offset().left

            var cx = se.pageX - drag.x
            $parent.css('left', left + cx)
            var cy = se.pageY - drag.y
            $parent.css('top', top + cy)

            $target.data('drag', {x: se.pageX, y: se.pageY})

        } else if (type == 'mousedown') {
            var se = e.originalEvent

            $target.data('drag', {x: se.pageX, y: se.pageY})

        } else {
            $target.data('drag', null)
        }
    }

    //清空数据
    PtyxeleLoad.prototype.clearLoad = function () {
        var $list = this.$load.find('.layui_upload_list')

        for (var i = 0; i < $list.length; i++) {
            $list.eq(i).find('.ptcs-load-delete').trigger('click')
        }

    }

    //添加值
    PtyxeleLoad.prototype.addValue = function (value) {
        var values = this.value ? this.value : this.value = new Array()
        values.push(value)


        var fileNum = this.fileNum

        if (!fileNum) {
            this.fileNum = 0
            fileNum = 0
        }

        fileNum++
        this.fileNum = fileNum

        this.$element[0].value = this.getValue()
    }

    //获取值
    PtyxeleLoad.prototype.getValue = function () {
        if (!this.value) return ''

        var strVal = ''

        for (var i = 0; i < this.value.length; i++) {
            if (this.value[i]) {
                strVal += ',' + this.value[i]
            }
        }

        if (!strVal) return ''

        return strVal.substring(1)
    }

    //删除值
    PtyxeleLoad.prototype.delValue = function (value) {
        var values = this.value

        if (!values) {
            this.value = []
            values = this.value
        }

        for (var i = 0; i < values.length; i++) {
            if (value == values[i]) {
                values.splice(i, 1)
                var fileNum = this.fileNum

                if (!fileNum) {
                    this.fileNum = 0
                    fileNum = 0
                }

                if(fileNum > 0){
                    fileNum--
                }
                this.fileNum = fileNum
            }
        }
        this.$element[0].value = this.getValue()
    }

    //重写值
    PtyxeleLoad.prototype.val = function (value) {
        if (value == undefined || value == null) {

            if (!this.value) return ''

            var values = ''
            for (var i = 0; i < this.value.length; i++) {
                if (this.value[i]) {
                    values += ',' + this.value[i]
                }
            }

            if (values) {
                values = values.substring(1)
            }

            return values

        } else {
            this.clearLoad()
            if (typeof  value == 'string') {
                var values = value.split(',')

                for (var i = 0; i < values.length; i++) {
                    if (values[i]) {
                        this.addFileByOssKey(values[i], this.options.ossParams)
                        this.addValue(values[i])
                    }
                }

            } else if (value instanceof Array) {
                for (var i = 0; i < value.length; i++) {
                    if (value[i]) {
                        this.addFileByOssKey(value[i], this.options.ossParams)
                        this.addValue(value[i])
                    }

                }
            }


        }
    }

    function Plugin(options) {
        return this.each(function () {

            var $this = $(this)

            var data = $this.data(PtyxeleLoad.PACE)

            Ptyxele()

            if (!data) {

                var dd = $.extend(true, PtyxeleLoad.prototype, Ptyxele.prototype, PtyxeleLoad.prototype)

                $this.data(PtyxeleLoad.PACE, (data = new dd.constructor(this, options)))
            }
        })
    }

    function SelectValue(value) {

        var $this = $(this), data = $this.data(Ptyxele.PTYXELE)

        if (!data) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }

        var module = data.module.replace(Ptyxele.PREFIX, '')


        if (module != 'load') {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        } else {
            data = $this.data(PtyxeleLoad.PACE)
            if (data) {
                return data.val(value)
            } else {
                return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
            }
        }
    }

    var oldVal = $.fn.val
    $.fn.ptyxeleLoad = Plugin
    $.fn.val = SelectValue


    $(window).on('load', function () {
        $('[ptyx-load],[ptyx-data*="module:load"]').each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxeleLoad()

        })
    })

    $(document).on(' create.load.ptyxele-api', '[ptyx-load],[ptyx-data*="module:load"]', function () {
        $(this).ptyxeleLoad()
    })


}(jQuery);

/**
 * Created by chenzp on 18-3-12.
 */
+function ($) {

    var PtyxeleProvinces = function (ele, options) {
        this.$element = $(ele)
        this.options = $.extend({}, PtyxeleProvinces.DEFAULTS, options)
        this.init()
    }


    PtyxeleProvinces.MODULE = {
        province: 'province'
        , city: 'city'
        , area: 'area'
        , link: 'link'
    }

    PtyxeleProvinces.PACE = "ptyx.province"

    PtyxeleProvinces.ID_PREFIX = 'ptyx_province_'

    PtyxeleProvinces.DEFAULTS = {
        cshow: 'name'
        , cvalue: 'id'
        , cpid: 'pid'
        , placeholder: {
            province: '请选择省份'
            , city: '请选择城市'
            , area: '请选择地区'
        }
    }

    //初始化
    PtyxeleProvinces.prototype.init = function () {

        this.mergeOption()

        this.initSelect()

        this.initEvent()
    }

    PtyxeleProvinces.prototype.initSelect = function () {
        var opt = this.options
        var $this = this

        var str = '<div class="layui-unselect layui-form-select">' +
            '   <div class="layui-select-title">' +
            '       <input type="text"  class="layui-input layui-unselect">' +
            '       <i class="layui-edge"></i>' +
            '   </div>' +
            '   <dl class="layui-anim layui-anim-upbit" style="">' +
            '   </dl>' +
            '</div>'

        var $str = $(str)
        this.$select = $str
        this.$input = $str.find('input')
        this.$dl = $str.find('dl')

        this.$dl.append('<dd lay-value="" value="" class="layui-select-tips">' + opt.placeholder + '</dd>')
        this.$input.attr('readonly', true).attr('placeholder', opt.placeholder)

        this.$input.on('click', function () {
            var selchecked = 'layui-form-selected'
            var parent = '.layui-unselect.layui-form-select'
            $(parent).removeClass(selchecked)
            $this.show()
        })

        $str.find('dd').on('click', $.proxy(this.checkedEvent, this))

        this.$element.after($str)


        this.$element.attr('readonly', true).hide()

    }

    //初始化事件
    PtyxeleProvinces.prototype.initEvent = function () {
        var $this = this
        var opt = this.options
        // $(document).on('click', function (e) {
        //     var $target = $(e.target)
        //     var select = '.layui-unselect'
        //     var $parent = $target.closest(select)
        //     if ($parent.length > 0) {
        //         return
        //     } else {
        //         $this.hide()
        //     }
        // })

    }

    //存储数据
    PtyxeleProvinces.prototype.storeData = function (data) {

        var storeData = new Object()

        var opt = this.options

        if (typeof data == 'object' && !data instanceof Array) {
            storeData[data[opt.cvalue]] = data
        } else if (data instanceof Array) {
            for (var i = 0; i < data.length; i++) {
                var ele = data[i]
                storeData[ele[opt.cvalue]] = ele
            }
        }

        this.store = storeData

    }

    //加载数据
    PtyxeleProvinces.prototype.load = function (column, id, call) {

        if (!column) return

        var $this = this
        var opt = this.options

        var serData = new Object()
        if (id != undefined && id != null) {
            serData[column] = id
        }

        this.$select.find('dd').not('.layui-select-tips').remove()
        this.store = []
        this.$checked = null
        this.$input.val('')

        $.ajax({
            dataType: 'json'
            , async: false
            , url: opt.url
            , data: serData
            , success: function (res) {
                var resData = new Object()

                if (!res.successful) {
                    if (rs.msg) {
                        throw new Error(res.msg)
                    }
                    throw new Error('数据请求失败')
                } else {
                    if (res.result) {
                        resData = res.result
                    }
                }

                $this.storeData(resData)
                $this.draw(resData)

                if (typeof call == 'function') {
                    call()
                }

            }
            , error: function (e) {
                throw new Error(e)
                console.info('数据加载失败')
            }
        })

    }

    //渲染数据
    PtyxeleProvinces.prototype.draw = function (data) {
        if (!data) return

        if (!data instanceof Array) return

        var opt = this.options
        var strOpt = '<dd></dd>'

        for (var i = 0; i < data.length; i++) {
            var ele = data[i]
            var $str = $(strOpt)

            $str.on('click', $.proxy(this.checkedEvent, this))
            $str.html(ele[opt.cshow]).attr({'value': ele[opt.cvalue]})
            this.$select.find('dl').append($str)
        }

    }

    PtyxeleProvinces.prototype.hide = function () {
        this.$select.removeClass('layui-form-selected')
    }

    PtyxeleProvinces.prototype.show = function () {
        this.$select.addClass('layui-form-selected')
    }

    PtyxeleProvinces.prototype.checkedEvent = function (e) {
        var $target = $(e.currentTarget)

        this.$element.find('option').remove()

        if ($target.hasClass('layui-select-tips')) {

            //判断选中的值是否发生变化触发change事件
            var $oldChecked = this.$checked
            this.$checked = null
            if($oldChecked){
                this.$element.trigger('change')
            }

            this.hide()
            this.$input.val('')
            this.updateChildVal('')
            this.$element.trigger('click')
            return
        }

        var opt = this.options

        // if(this.$checked && this.$checked.is($target)) return

        this.$select.find('dd.layui-this').removeClass('layui-this')
        $target.addClass('layui-this')

        //判断选中的值是否有变化触发唱歌事件
        var $oldChecked = this.$checked
        this.$checked = $target
        if(!$oldChecked ||($oldChecked && $oldChecked.attr('value') != this.$checked.attr('value'))){
            this.$element.trigger('change')
        }

        var val = $target.attr('value')

        var ele = this.store[val]

        this.$input.val(ele[opt.cshow])

        var $option = $('<option value="' + val + '" selected></option>')
        this.$element.append($option)
        $option.prop('selected', true)
        this.updateChildVal(val)
        this.hide()
        this.$element.trigger('click')
    }

    PtyxeleProvinces.prototype.updateChildVal = function (val) {
        var $child = this.$element.data(Ptyxele.LINK)
        if ($child && $child.length > 0) {
            $child.pval(val)
        }

    }

    //重写值
    PtyxeleProvinces.prototype.val = function (value) {
        if (value == undefined || value == null) {
            if (!this.$checked) return ''

            var id = this.$checked.attr('value')
            return id + ''
        } else {
            var opt = this.options
            var $this = this

            if (!this.store || !this.store[value]) {
                this.load(opt.cvalue, value, function () {
                    var $target = $this.$select.find('dd[value="' + value + '"]')
                    if ($target.length == 0) {
                        throw new Error('数据异常')
                    }

                    $this.show()
                    $target.trigger('click')
                })
                return
            }

            var $target = $this.$select.find('dd[value="' + value + '"]')
            if ($target.length == 0) {
                throw new Error('数据异常')
            }

            this.show()
            $target.trigger('click')
        }


    }

    function Plugin(options) {
        return this.each(function () {
            var $this = $(this)

            var data = $this.data(PtyxeleProvinces.PACE)

            Ptyxele()

            if (!data) {

                var dd = $.extend(true, PtyxeleProvinces.prototype, Ptyxele.prototype, PtyxeleProvinces.prototype)

                $this.data(PtyxeleProvinces.PACE, (data = new dd.constructor(this, options)))

                var ptyxele = $this.data(Ptyxele.PTYXELE)

                var val = $this.val()

                var value = data.options.value

                val = value ? value : val

                if ((val == null || val == '') && ptyxele.module == 'province') {
                    data.load(data.options.cpid, 0)
                } else {
                    if (val == null || val == undefined) {
                        if (data.options.link) {
                            var $parent = $(data.options.link)

                            if ($parent.length > 0 && $parent.val()) {
                                $parent.val($parent.val())
                            }
                        }
                    } else {
                        if (val) {
                            data.val(val)
                        }
                    }
                }
            }


        })

    }

    function SelectValue(value) {

        var $this = $(this), data = $this.data(Ptyxele.PTYXELE)

        if (!data) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }

        var module = data.module.replace('ptyx-', '')


        if (!PtyxeleProvinces.MODULE[module]) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        } else {
            data = $this.data(PtyxeleProvinces.PACE)
            if (data) {
                return data.val(value)
            } else {
                return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
            }
        }
    }

    function SelectPidValue(value) {

        var $this = $(this), data = $this.data(Ptyxele.PTYXELE)

        if (!data) return

        var opt = data.options


        var jqueryData = $this.data(PtyxeleProvinces.PACE)
        var $option = $('<option value="" selected></option>')
        jqueryData.$element.append($option)
        $option.prop('selected', true)

        jqueryData.load(jqueryData.options.cpid, value)


        if (data.module == 'city') {
            jqueryData.updateChildVal('')
        }

    }

    function ParentId() {
        var $this = $(this)

        var data = $this.data(PtyxeleProvinces.PACE)

        if (!data) return null;

        return data.options.link
    }


    var oldVal = $.fn.val
    $.fn.ptyxProvinces = Plugin
    $.fn.val = SelectValue
    $.fn.pval = SelectPidValue

    $.fn.ptyxProvinceParentId = ParentId


    var apis = ''
    var apiAttr = ''

    $.each(PtyxeleProvinces.MODULE, function (k, v) {
        apiAttr += ',[ptyx-' + k + '],[ptyx-data*="module:' + k + '"]'
        apis += ' create.' + k + '.ptyxele-api'
    })


    $(window).on('load', function () {
        $(apiAttr.substring(1)).each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxProvinces()
        })
    })


    $(document).on(apis.substring(1), apiAttr.substring(1), function () {
        $(this).ptyxProvinces()
    })


}(jQuery);

/**
 * Created by chenzp on 18-02-26.
 */
+function ($) {

    var PtyxeleSelect = function (ele, options) {
        this.$element = $(ele)
        this.options = $.extend({}, PtyxeleSelect.DEFAULTS, options)
        this.init()
    }

    PtyxeleSelect.MODULE = {
        group: 'group'
        , goods: 'goods'
        , product: 'product'
        , supplier: 'supplier'
        , buyer: 'buyer'
        , unit: 'unit'
        , operator: 'operator'
        , factory: 'factory'
        , brand: 'brand'
        , salecustomer: 'salecustomer'
        , account: 'account'
        , goodssort: 'goodssort'
        , pcommonname: 'pcommonname'
        , putil: 'putil'
        , pspec: 'pspec'
        , pfactory: 'pfactory'
        , daddress: 'daddress'
    }

    PtyxeleSelect.PACE = 'ptyx.select'


    PtyxeleSelect.DEFAULTS = {
        /**
         * 下拉框占位符默认值
         * 不同类型下拉框组件默认值不一样
         *  可以通过js重写值，也可以直接在标签修改placeholder值都可以
         */
        placeholder: {
            group: '请选择集团'
            , goods: '请选择商品'
            , product: '请选择产品'
            , supplier: '请选择供应商'
            , buyer: '请选择采购商'
            , unit: '请选择单位'
            , operator: '请选择运营人员'
            , factory: '请选择厂家'
            , brand: '请选择品牌'
            , salecustomer: '请选择客户'
            , account: '请选择用户'
            , goodssort: '请选择商品分类'
            , pcommonname: '请选择通用名称'
            , putil: '请选择单位'
            , pspec: '请选择规格'
            , pfactory: '请选择厂家'
            , daddress: '请选择收货地址'
        }
        /**
         * 主题，可选值有default，classic  theme可以是缺省值默认未default  标签是调用权限大于js调用
         * 一。如果是标签初始化，有三种方式初始化   调用权限 1>2=3
         * 1.直接属性初始化                     <select  ptyx-theme-classic></select>
         * 2.在ptyx-data中直接初始化            <select ptyx-data="{module:goods,theme:default}"></select>
         * 3.在ptyx-goods或相关的组件初始化      <select ptyx-goods="{theme:default}"></select>
         * 二。js初始化
         * 1.                                $(object).ptyxeleSelect({theme:'default'})
         *
         */
        , theme: 'default'
        /**
         * 是否可以支持多选，默认为false  标签是调用权限大于js调用
         * 一、标签式初始化也是有三种方式   调用权限 1>2=3
         * 1.直接通过属性初始化                <select ptyx-box></select>
         * 2.在ptyx-data中初始化             <select ptyx-data="{module:goods,box:true}"></select>
         * 3.在ptyx-goods等相关组件初始化      <select ptyx-goods="{box:true}"></select>
         * 二、js初始化
         * 1.                              $(object).ptyxeleSelect({box:true})
         */
        , box: false
        /**
         * 默认请求地址，这个可以通过配置设定，必填，建议在全局中设置,也可以通过标签与js修改，但是这两种方式修改，只对当前对象有效不影响全局值  标签是调用权限大于js调用
         * 一、标签式初始化有三种方式
         * 1.直接通过属性初始化              <select ptyx-url="http://www.ptyx.com/goods/data"></select>
         *二、js初始化
         * 1.                            $(object).ptyxeleSelect({url:'http://www.ptyx.com/goods/data'})
         */
        // , url: ''
        /**
         * 设置选中值字段
         */
        , cvalue: 'id'
        /**
         * 默认显示几条数据默认为10条
         */
        , num: 10
        /**
         * 下拉的数据是否去重
         */
        , isGroup:false
        /**
         * 下拉框定时隐藏  默认为五秒
         */
        , hide: 5000
        /**
         * 多个以逗号隔开，显示顺序以字段字符先后为主
         */
        , show: 'name,no'
        /**
         * 是否把框的值set到select中
         */
        , isEnterValue: false
        /**
         * 是否可以输入默认为flase
         */
        , readonly: false
        /**
         * 可以设定本地值 也可以直接在标签通过<option></option>设定值
         */
        , data: {}
        /**
         * 设定默认值
         */
        , value: ''
        /**
         * 默认false，可以操作true只能查看
         */
        /**
         * 第一次获取焦点加载数据
         */
        ,preload:false
        /**
         * 清空输入框按钮，默认为true
         */
        ,isClearBtn:true
        /**
         * 初始化完加载数据
         */
        ,initload:false

        , see: false
        /**
         * 获取焦点触发事件
         */
        // , focusin: function () {
        //     console.info('获取焦点')
        // }
        /**
         * 失去焦点触发事件
         */
        // , focusout: function () {
        //     console.info('失去焦点')
        //
        // }
        /**
         * 选中触发事件
         */
        , checked: function (checkValue) {
            // console.info('选中')
        }
        /**
         * 返回结果集数据触发事件
         * @param data
         */
        // , response: function (data) {
        //
        // }

        /**
         *
         * 渲染完触发事件
         */
        // ,drawFn:function ($list,data) {
        //
        // }


    }

    PtyxeleSelect.prototype.init = function () {
        var tagName = this.$element[0].tagName

        if (tagName != 'SELECT') throw new Error('标签不正确')

        if(this.options.module){
            this.$element.data(Ptyxele.PTYXELE,{module:this.options.module,ptyxele_module:Ptyxele.PREFIX+this.options.module})
            this.mergeOption()
        }else{
            var pdata = this.$element.data(Ptyxele.PACE)

            if (pdata && pdata.ptyxele && pdata.ptyxele.module) {
                this.mergeOption()
            } else {
                var placeholder = this.$element.attr('placeholder')
                this.options.placeholder = placeholder ? placeholder : '请选择'
            }
        }



        // console.info(this.$element.data(Ptyxele.PACE))

        var opt = this.options

        if (opt.see) {
            opt.readonly = true
        }
        //把要显示的字段转未数组
        if (!opt.show) throw new Error('show数据不能为空')

        //数据字段处理
        if (typeof opt.show == 'string') {
            this.showCol = opt.show.split(',')
            this.showColLen = opt.show.split(',').length
        } else if (opt.show instanceof Array) {
            this.showCol = opt.show
            this.showColLen = opt.show.length
        }

        this.category = !opt.readonly && opt.box ? 'box' : 'select'

        //设置默认值
        if (opt.value) {
            if (typeof opt.value == 'number') {
                this.value = [opt.value + '']
            } else if (typeof opt.value == 'string') {
                this.value = opt.value.split(',')
            } else if (opt.value instanceof Array) {
                var arr = new Array()
                for (var i = 0; i < opt.value.length; i++) {
                    arr.push(opt.value[i] + '')
                }
                this.value = arr
            } else {
                this.value = []
            }
            opt.value = []
        } else {
            this.value = []
        }

        if (!opt.box && this.value && this.value.length > 1) throw new Error('单选下拉框，默认值不能存在多个')

        //初始化事件
        this.initEvent()
        this.$element.hide()
        this.createSelectDiv()
        //初始化下拉框
        this.initSelect()
        //初始化默认值
        this.initDefaultValue()


        //初始化时是否要加载数据
        if(opt.initload){
            this.updateSelect('', true)
        }

        if (opt.add) {
            opt.isEnterValue = true
        }

    }

    // 初始化事件
    PtyxeleSelect.prototype.initEvent = function () {
        var $this = this
        //设置点击事件
        // $(document).on('click', function (e) {
        //     var $target = $(e.target)
        //     var $parent = $target.closest('.ptcs-select-title')
        //     var $parent2 = $target.closest('.ptcs-select-input')
        //     var $dl = $target.closest('.ptcs-anim')
        //     var selected = 'layui-form-selected'
        //
        //     if ($target.hasClass('ptcs-select-title') || $parent.length > 0 || $parent2.length > 0) {
        //         return
        //     } else if ($dl.length > 0 || $dl.hasClass('ptcs-anim')) {
        //         if (!($this.options.box && $this.category == 'select')) {
        //             $this.$select.removeClass(selected)
        //         }
        //
        //     } else {
        //         $('.layui-select-title').parent().removeClass(selected)
        //     }
        // })
    }

    //初始化默认值
    PtyxeleSelect.prototype.initSelect = function () {
        var $options = this.$element.find('option')
        var options = this.options

        var storeData = new Array()
        //需要重新加载数据
        var againData = new Array()

        //验证标签数据是否完整
        for (var i = 0; i < $options.length; i++) {
            var $obj = $options.eq(i)
            var data = $obj.attr('data')
            if (!data) {
                continue
            }
            data = eval('(' + data + ')')
            if (!data) {
                throw new Error('数据格式不正确')
            }
            if (!data[options.cvalue]) {
                throw new Error('数据格式不正确')
            }

            if (options.theme == 'default' && !data[this.showCol[0]]) {
                againData.push(data[options.cvalue])
            }

            if (options.theme == 'classic' && (!data[this.showCol[0]] || !data[this.showCol[1]])) {
                againData.push(data[options.cvalue])
            }

            storeData.push(data)
        }

        //验证js初始化数据是否完整
        if (options.data) {
            for (var i = 0; i < options.data.length; i++) {
                var edata = options.data[i]
                if (!edata) {
                    continue
                }
                if (!edata[options.cvalue]) {
                    throw  new Error('数据格式不正确')
                }
                if (options.theme == 'default' && !edata[this.showCol[0]]) {
                    againData.push(edata[options.cvalue])
                }

                if (options.theme == 'classic' && (!edata[this.showCol[0]] || !edata[this.showCol[1]])) {
                    againData.push(edata[options.cvalue])
                }
                storeData.push(edata)
            }
        }


        //不完整数据重新从服务器记载数据
        var loadValue = this.loadValue(againData)

        if (loadValue && loadValue.length > 0) {
            for (var i = 0; i < storeData.length; i++) {
                var element = storeData[i]
                for (var j = 0; j < loadValue.length; j++) {
                    var ele = loadValue[j]
                    if (element[options.cvalue] == ele[options.cvalue]) {
                        storeData.splice(i, 1, ele)
                        break
                    }
                }
            }
        }

        //更新下来框
        this.changeSelect(storeData)

        //保存数据
        this.store(storeData)
    }

    //缓存服务器数据
    PtyxeleSelect.prototype.store = function (data) {
        if (!data) {
            return
        }

        var options = this.options

        var storeData = this.storeData
        if (!storeData) {
            storeData = new Object()
            this.storeData = storeData
        }

        if (data instanceof Array) {

            if (data.length == 0) {
                return
            }

            for (var i = 0; i < data.length; i++) {
                var ele = data[i]
                var val = ele[options.cvalue]
                if (!val) {
                    continue
                }

                storeData[val] = ele
            }

        } else if (data instanceof Object) {
            var val = data[options.cvalue]
            if (!val) {
                return
            }

            storeData[val] = data
        }

    }

    //根据value值多个value值以逗号隔开，到服务器请求
    PtyxeleSelect.prototype.loadValue = function (value) {
        if (!value) {
            return null
        }

        if (!value instanceof Array) {
            throw new Error('数据格式不正确')
        }

        if (value.length == 0) {
            return null
        }

        var options = this.options

        $.ajax({
            url: options.url
            , dataType: 'json'
            //这里我们同步加载数据
            , async: false
            , data: {id: value}
            , success: function (res) {
                if (!res.successful) {
                    if (rs.msg) {
                        throw new Error(res.msg)
                    }
                    throw new Error('数据请求失败')
                } else {
                    if (res.result) {
                        return res.result
                    }
                }
            }
            , error: function (e) {
                console.info('数据请求失败')
                console.info(e)
            }
        })
    }

    //异步请求数据更新下来框数据
    PtyxeleSelect.prototype.updateSelect = function (word, isUpdateValue) {
        var opt = this.options
        var $this = this

        var load = opt.initload ? true:opt.preload ? true:false
        //第一次获取焦点加载数据
        if(!word && !load ){
            var i = 0
            var arr = new Array()
            for (d in this.storeData) {
                if (i == opt.num) break
                arr.push(this.storeData[d])
                i++
            }
            var data = arr.slice(0, opt.num)
            this.changeSelect(data, word, isUpdateValue)
            return
        }

        if(opt.initload){
            opt.initload = false
        }



        var cache = this.cache
        if (!cache) {
            cache = new Object()
        }

        if (cache[word]) {
            var data = cache[word]
            this.changeSelect(data.slice(0, opt.num), word, isUpdateValue)
            return
        }

        //
        // //这里暂不从服务器请求数据，模拟服务器数据
        // var result = [
        //     {id: 52, name: 'book', no: 'N234321'}
        //     , {id: 53, name: 'origen', no: 'N254321'}
        //     , {id: 54, name: 'number', no: 'N2344321'}
        //     , {id: 55, name: 'name', no: 'N2343421'}
        //     , {id: 56, name: 'search', no: 'N2344321'}
        //     , {id: 57, name: 'look', no: 'N2344321'}
        //     , {id: 18, name: 'read', no: 'N2345321'}
        //     , {id: 19, name: 'game', no: 'N23463721'}
        //     , {id: 20, name: 'add', no: 'N2343721'}
        //     , {id: 21, name: 'create', no: 'N2348321'}
        //     , {id: 22, name: 'time', no: 'N2343821'}
        //     , {id: 23, name: 'computer', no: 'N2342321'}
        //     , {id: 24, name: 'mobile', no: 'N2343291'}
        //     , {id: 25, name: 'bed', no: 'N2343281'}
        //     , {id: 26, name: 'box', no: 'N5234321'}
        //     , {id: 27, name: 'paper', no: 'N2434321'}
        //     , {id: 28, name: 'line', no: 'N2324321'}
        //     , {id: 29, name: 'flower', no: 'N24344321'}
        //     , {id: 30, name: 'lieght', no: 'N23446321'}
        //     , {id: 31, name: 'height', no: 'N23436621'}
        //     , {id: 32, name: 'dog', no: 'N23437921'}
        //     , {id: 33, name: 'cat', no: 'N23743021'}
        //     , {id: 34, name: 'banana', no: 'N23254321'}
        //     , {id: 35, name: 'apple', no: 'N23436321'}
        //     , {id: 36, name: 'orange', no: 'N234364521'}
        //     , {id: 37, name: 'noodles', no: 'N23498321'}
        //     , {id: 38, name: 'electric', no: 'N23894321'}
        //     , {id: 39, name: 'strawberry', no: 'N2354321'}
        //     , {id: 40, name: 'pear', no: 'N2343521'}
        //     , {id: 41, name: 'litch', no: 'N23444321'}
        //     , {id: 42, name: 'longan', no: 'N23478321'}
        //     , {id: 43, name: 'hawthorn', no: 'N23474321'}
        //     , {id: 44, name: 'melon seeds', no: 'N23454321'}
        //     , {id: 45, name: 'lemon', no: 'N23434521'}
        // ]
        //
        // var matchRes = new Array()
        // for (var z = 0; z < result.length; z++) {
        //     var ele = result[z]
        //     if (ele.name.indexOf(word) != -1) {
        //         matchRes.push(ele)
        //     }
        // }
        // cache[word] = matchRes.slice(0, opt.num)
        // this.store(matchRes.slice(0, opt.num))
        // this.changeSelect(matchRes)
        //
        // return


        var reqData = {name: word}

        //重写请求参数
        this.$element.trigger('event.select.requestData.ptyxele-api',reqData)

        if(opt.requestData){
            $.extend(true, reqData, opt.requestData)
        }

        $.ajax({
            url: opt.url
            , dataType: 'json'
            //这里我们同步加载数据
            // , async: false
            , data: reqData
            , success: function (res) {
                if (!res.successful) {
                    if (rs.msg) {
                        throw new Error(res.msg)
                    }
                    throw new Error('数据请求失败')
                } else {

                    if (opt.response && typeof opt.response == 'function') {
                        var resData = opt.response(res)
                        if (resData) {
                            $this.store(resData)
                            $this.changeSelect(resData, word, isUpdateValue)
                            cache[word] = resData
                        }
                    } else {
                        if (res.result) {
                            $this.store(res.result)
                            $this.changeSelect(res.result, word, isUpdateValue)
                            cache[word] = res.result
                        }
                    }

                }
            }
            , error: function (e) {
                console.info('数据请求失败')
                console.info(e)
            }
        })

    }

    //更新下拉框列表
    PtyxeleSelect.prototype.changeSelect = function (data, word, isUpdateValue) {
        if (!data) return

        if (!data instanceof Array) return

        var opt = this.options
        var $sel = this.$select

        var $optCheck = $sel.find('.layui-select-tips .layui-form-checkbox')

        if ($optCheck.hasClass('layui-form-checked')) $optCheck.removeClass('layui-form-checked')

        $sel.find('dd').not('.layui-select-tips').remove()
        var str = this.category == 'select' && opt.box ? '<dd><span></span><em> <input type="checkbox" style="display: none;"> <div class="layui-unselect layui-form-checkbox" lay-skin=""> <i class="layui-icon"></i> </div> </em> </dd>' : '<dd><span></span></dd>'

        var singleEle = ''

        //显示添加按钮
        this.$add ? this.$add.show() : null

        //数据的去重
        this.groupData(data)

        var listDd = new Array()

        for (var i = 0; i < data.length; i++) {
            var $str = $(str)
            var ele = data[i]
            $str.attr('lay-value', ele[opt.cvalue])

            var colName = ''

            if (opt.theme == 'classic') {
                colName = ele[this.showCol[0]] + '(' + ele[this.showCol[1]] + ')'
            } else {
                colName = ele[this.showCol[0]]
            }
            $str.find('span').text(colName)

            $sel.find('dl').append($str)
            //添加选中与取消事件
            $str.on('click', $.proxy(this.checkEvent, this))

            listDd.push($str)

            var j = $.inArray(ele[opt.cvalue] + '', this.value)

            if (j != -1) {

                if (this.category == 'select') {
                    var values = this.$select.find('.layui-input').data('value')
                    if (values && $.inArray(ele[opt.cvalue], values) != -1) {
                        $str.addClass('layui-this')
                        if ($str.find('.layui-form-checkbox').length > 0) {
                            $str.find('.layui-form-checkbox').addClass('layui-form-checked')
                        }
                    }

                } else {
                    var $li = this.$box.find('li[lay-value="' + ele[opt.cvalue] + '"]')
                    if ($li.length > 0) {
                        $str.addClass('layui-this')
                    }

                }

            }



            //判断是否显示添加按钮
            if (opt.add && word == ele[this.showCol[0]]) {
                this.$add.hide()
            }

            // if (isUpdateValue && word && word == ele[this.showCol[0]]) {
            //     this.$select.find('.layui-input').val(ele[this.showCol[0]])
            //     this.value = [ele[opt.cvalue]]
            //     this.hide()
            // }

            singleEle = ele
        }



        if (opt.drawFn && typeof  opt.drawFn == 'function') {
            opt.drawFn(listDd,this.$element)
        }


        if(isUpdateValue) {
            //渲染的次数
            this.times = this.times >= 0  ? this.times+1:0

            //渲染后触发的事件
            this.$element.trigger('event.select.drawed.ptyxele-api', {list:listDd,times:this.times})

            if(opt.drawed && typeof opt.drawed == 'function'){
                opt.drawed({list:listDd,times:this.times})
            }
        }




        // if (isUpdateValue && data.length == 1) {
        //     this.$select.find('.layui-input').val(singleEle[this.showCol[0]])
        //     this.value = [singleEle[opt.cvalue]]
        //     this.hide()
        // }
    }

    //数据的去重
    PtyxeleSelect.prototype.groupData = function(data){
        var opt = this.options
        if(opt.isGroup){
            groupData = {}
            for(var i=0;i<data.length;i++){
                ele = data[i]

                var colName = ''
                if (opt.theme == 'classic') {
                    colName = ele[this.showCol[0]] + '(' + ele[this.showCol[1]] + ')'
                } else {
                    colName = ele[this.showCol[0]]
                }

                if(groupData[colName]){
                    data.splice(i,1)
                    i--
                }
                groupData[colName] = true
            }
        }

    }

    //初始化默认选中的值
    PtyxeleSelect.prototype.initDefaultValue = function () {
        var $this = this
        var options = this.options


        if (!this.value) {
            return
        }

        if (this.options.isEnterValue && !this.options.add && !this.options.box) {
            this.updateSelect(this.value[0], true)
            this.$select.find('.layui-input').val(this.value[0])
            return
        }

        var isLoad = false
        var valueData = new Array()

        var loadValue = new Array()

        for (var i = 0; i < this.value.length; i++) {
            var ele = this.value[i]
            if (!this.storeData[ele]) {
                isLoad = true
                loadValue.push(ele)
                continue
            } else {
                valueData.push(this.storeData[ele])
            }
        }

        if (!isLoad) {
            this.changeSelect(valueData)
            //设置选中值
            this.selectedValue(valueData)
            // this.elementSelected(valueData)
            return
        }

        var strLoadVal = ''
        for (var i = 0; i < loadValue.length; i++) {
            strLoadVal += ',' + loadValue[i]
        }

        if (strLoadVal) strLoadVal = strLoadVal.substring(1)


        if (!options.url) {
            throw new Error('地址不能为空')
        }

        var sdata = new Object()
        sdata.column = options.cvalue
        sdata.id = strLoadVal


        $.ajax({
            url: options.url
            , dataType: 'json'
            , data: sdata
            , success: function (res) {
                if (!res.successful) {
                    if (res.msg) {
                        console.info(res.msg)
                    }
                    return
                }

                if (!res.result) {
                    throw new Error('未查询到设定的值')
                }

                if (!options.box && res.result.length > 1) {
                    throw new Error('因为是单选，查询的值有不能有多个')
                }

                for (var z = 0; z < res.result.length; z++) {
                    valueData.push(res.result[z])
                }

                //保存值
                $this.store(res.result)

                $this.changeSelect(valueData)
                //设置选中值
                $this.selectedValue(valueData)
                // $this.elementSelected(valueData)
            }
            , error: function (e) {
                console.info('查询默认值，请求数据失败');
                console.info(e);
            }
        })
    }

    //设置选中值
    PtyxeleSelect.prototype.selectedValue = function (data) {

        if (!data) {
            return
        }

        var opt = this.options

        var valueData = new Array()

        if (typeof data == 'string' || typeof data == 'number') {
            data = this.storeData[data]
            if (!data) {
                return
            }
            valueData.push(data)
        } else if (data instanceof Object && !data instanceof Array) {
            if (!data[opt.cvalue]) {
                return
            }

            data = this.storeData[data[opt.cvalue]]
            if (!data) {
                return
            }
            valueData.push(data)
        } else if (data instanceof Array) {
            valueData = data
        } else {
            return
        }

        for (var i = 0; i < valueData.length; i++) {
            var element = valueData[i]
            var val = element[opt.cvalue]
            var $checked = this.$select.find('dd[lay-value="' + val + '"]')
            $checked.trigger('click')
        }
    }

    //动态创建下拉框
    PtyxeleSelect.prototype.createSelectDiv = function () {

        var opt = this.options

        var $this = this

        var str = '<div class="layui-unselect ptcs-select layui-form-select">' +
            '<div class="layui-select-title ptcs-select-title">' +
            '<input type="text" class="layui-input layui-unselect">' +
            // '<i class="layui-more">...</i>' +
            // '<i class="ptcs-select-del-btn"></i>' +
            '</div>' +
            '<dl class="layui-anim layui-anim-upbit ptcs-anim">' +
            '<dd lay-value="" class="layui-select-tips"><span></span></dd>' +
            '</dl>' +
            '</div>'

        var $str = $(str)
        $str.find('.layui-select-tips>span').text(opt.placeholder)

        //是否要添加增加按钮
        if (opt.add) {
            var $add = $('<e style="color:#5fb878;" class="layui-more">✚</e>')
            $str.find('input').after($add)
            this.$add = $add
            $add.on('click', function (e) {
                $this.$element.trigger('event.select.add.ptyxele-api', $this.$add)
            })
        }else if(opt.isClearBtn){
            var $clear = $('<i class="ptcs-select-del-btn"></i>')
            $str.find('input').after($clear)
            this.$clearBtn = $clear
            $clear.on('click', function (e) {
                $str.find('input').val('')
                $this.value = []
                $str.find('input').trigger('focusin')
                $this.$element.trigger('event.select.clear.ptyxele-api')
            })
        }

        var $selectInput = $str.find('.layui-input')

        $selectInput.attr('placeholder', opt.placeholder)

        // 输入框获取焦点事件
        $selectInput.on('focusin', $.proxy(this.focuseEvent, this))

        //输入框绑定键盘事件
        $selectInput.on('keyup', $.proxy(this.inputEvent, this))

        //上下移动下拉框选项事件
        $selectInput.on('keydown', $.proxy(this.selectMoveEvent, this))

        //输入框失去焦点事件
        $selectInput.on('focusout', function () {
            if (opt.focusout && typeof  opt.focusout == 'function') {
                opt.focusout()
            }

            if (!opt.isEnterValue) {
                if (!$this.value || $this.value.length == 0) {
                    $this.$select.find('.layui-input').val('')
                    $this.$element.trigger('event.nochecked.ptyxele-api')
                }
            }
        })

        //个请选择绑定事件（针对单选触发事件）
        $str.find('dd').on('click', $.proxy(this.optionsCheckEvent, this))


        if (this.category == 'box') {
            var sstr = '<span class="select2-container">' +
                '<span class="selection">' +
                '<ul style="">' +
                '<li class="ptcs-select-input"><input class="select2-search__field"></li>' +
                '</ul>' +
                '</span>' +
                '</span>'
            var $sstr = $(sstr)
            $sstr.find('input').attr('placeholder', opt.placeholder)
            // this.$element.after($sstr)
            $str.find('dl').css('top', 'auto').before($sstr)
            this.$box = $sstr

            // 获取焦点事件
            $sstr.find('input').on('focusin', $.proxy(this.focuseEvent, this))

            //输入框事件
            $sstr.find('input').on('keyup', $.proxy(this.inputEvent, this))

            //上下移动下拉框选项事件
            $sstr.find('input').on('keydown', $.proxy(this.selectMoveEvent, this))

            //输入框失去焦点事件
            $sstr.find('input').on('focusout', function () {
                if (opt.focusout && typeof  opt.focusout == 'function') {
                    opt.focusout()
                }
            })
        }


        if (opt.box && this.category == 'select') {
            $str.find('.layui-select-tips').append('<em>' +
                '<input type="checkbox" style="display: none;">' +
                '<div class="layui-unselect layui-form-checkbox" lay-skin="">' +
                '<i class="layui-icon"></i>' +
                '</div>' +
                '</em>')

            //全选与取消
            $str.find('.layui-form-checkbox').on('click', $.proxy(this.batchCheckEvent, this))
        }

        this.$element.after($str)
        this.$select = $str


        if (opt.readonly) {
            $str.find('input').attr('readonly', true)
        }

        if (this.category == 'box') {
            this.$select.find('.layui-select-title').hide()
        }
    }

    //隐藏下拉框
    PtyxeleSelect.prototype.hide = function () {
        if (this.$select.hasClass('layui-form-selected')) {
            this.$select.removeClass('layui-form-selected')
        }
    }

    //显示下来框
    PtyxeleSelect.prototype.show = function () {

        var winH = $(window).outerHeight()
        var scrollTop = $(document).scrollTop()
        var selTop = this.$select.offset().top
        var bottomH = scrollTop + winH - selTop
        var dlH = this.$select.find('dl').outerHeight()

        var up = 'layui-form-selectup'
        var selected = 'layui-form-selected'
        if (dlH > bottomH) {
            this.$select.addClass(up)
        } else {
            this.$select.removeClass(up)
        }
        this.$select.addClass(selected)

    }

    //批量选中与取消
    PtyxeleSelect.prototype.batchCheckEvent = function (e) {
        var $target = $(e.currentTarget)
        var opt = this.options
        var hasChecked = $target.hasClass('layui-form-checked')
        if (hasChecked) {
            this.$select.find('dd').removeClass('layui-this').find('.layui-form-checkbox').removeClass('layui-form-checked')
            this.$select.find('.layui-input').val('')
            this.value = []

            this.elementSelected('')

            // layui-unselect layui-form-checkbox layui-form-checked
        } else {
            var $check = this.$select.find('dd').not('.layui-this').not('.layui-select-tips')
            if ($check.length == 0) {
                return
            }

            if (opt.checked && typeof opt.checked == 'function') {
                for (var j = 0; j < $check.length; j++) {
                    opt.checked($check.eq(j).attr('lay-value'))
                }
            }

            $check.addClass('layui-this').find('.layui-form-checkbox').addClass('layui-form-checked')
            var $checked = this.$select.find('dd').not('.layui-select-tips')

            var names = ''
            var values = new Array()
            for (var i = 0; i < $checked.length; i++) {
                var val = $checked.eq(i).attr('lay-value')
                if (!val) {
                    throw new Error('数据异常')
                }
                var data = this.storeData[val]
                if (!data) {
                    throw new Error('数据异常')
                }
                names += ',' + data[this.showCol[0]]
                values.push(val)
            }

            if (names) {
                names = names.substring(1)
            }

            this.value = values
            this.$select.find('.layui-input').val(names)
            $target.addClass('layui-form-checked')

            this.elementSelected(values)
        }
    }

    //select设置选中
    PtyxeleSelect.prototype.elementSelected = function (value) {
        var eleVal = ''
        var valName = ''
        if (typeof  value == 'string' || typeof value == 'number') {
            eleVal = value + ''
            if(this.storeData[value]){
                var colName = this.showCol[0]
                valName = this.storeData[value][colName]
            }

        } else if (value instanceof Array) {
            // 多选的暂时不实现 数据名称回写option中
            for (var i = 0; i < value.length; i++) {
                eleVal += ',' + value[i]
            }

            if (eleVal) eleVal = eleVal.substring(1)
        }

        //select 设置选中值
        var $option = $('<option value="${eleVal}">${valName}</option>')
        this.$element.find('option').remove()
        this.$element.append($option)
        $option.prop('selected', true)
    }

    //单个选中与取消
    PtyxeleSelect.prototype.checkEvent = function (e) {

        var $target = $(e.currentTarget)
        var hasChecked = $target.hasClass('layui-this')
        var opt = this.options
        var $this = this

        var selchecked = 'layui-form-selected'

        //下拉框多选
        if (this.category == 'select' && opt.box) {

            var $opt = this.$select.find('.layui-select-tips .layui-form-checkbox')

            if (hasChecked) {
                if ($opt.hasClass('layui-form-checked')) {
                    $opt.removeClass('layui-form-checked')
                }
                $target.removeClass('layui-this').find('.layui-form-checkbox').removeClass('layui-form-checked')
                var $checked = this.$select.find('.layui-this')
                if ($checked.length == 0) {
                    this.value = []
                    this.$select.find('.layui-input').val('')
                    this.$select.find('.layui-input').data('value', [])
                } else {
                    var values = new Array()
                    var names = ''
                    for (var i = 0; i < $checked.length; i++) {
                        var $obj = $checked.eq(i)
                        var val = $obj.attr('lay-value')
                        if (!val) {
                            throw new Error('数据异常')
                        }

                        var data = this.storeData[val]

                        if (!data) {
                            throw new Error('数据异常')
                        }

                        names += ',' + data[this.showCol[0]]
                        values.push(val)
                    }

                    if (names) {
                        names = names.substring(1)
                    }
                    this.$select.find('.layui-input').val(names)
                    this.value = values
                    this.$select.find('.layui-input').data('value', values)

                    this.elementSelected(values)
                }
            } else {
                $target.addClass('layui-this').find('.layui-form-checkbox').addClass('layui-form-checked')
                var $check = this.$select.find('dd').not('.layui-this').not('.layui-select-tips')
                if ($check.length == 0) {
                    $opt.addClass('layui-form-checked')
                }

                var $checked = this.$select.find('.layui-this')
                var names = ''
                var values = new Array()
                for (var i = 0; i < $checked.length; i++) {
                    var val = $checked.eq(i).attr('lay-value')
                    if (!val) {
                        throw  new Error('数据异常')
                    }

                    var data = this.storeData[val]
                    if (!data) {
                        throw new Error('数据异常')
                    }
                    names += ',' + data[this.showCol[0]]
                    values.push(val)
                }

                this.value = values
                if (names) {
                    names = names.substring(1)
                }
                this.$select.find('.layui-input').val(names)
                this.$select.find('.layui-input').data('value', values)

                if (opt.checked && typeof  opt.checked == 'function') {
                    opt.checked(val)
                }

                this.elementSelected(values)
            }

        } else if (this.category == 'select' && !opt.box) {

            if (hasChecked) {
                $target.removeClass('layui-this')
                this.$select.find('.layui-input').val('')
                this.$select.find('.layui-input').data('value', [])

                this.value = []
                this.$select.removeClass(selchecked)
                this.elementSelected('')
                //下拉未选中事件
                this.$element.trigger('event.nochecked.ptyxele-api')
                //显示添加按钮
                this.$add ? this.$add.show() : null
                return
            }

            this.$select.find('.layui-this').removeClass('layui-this')
            $target.addClass('layui-this')
            var val = $target.attr('lay-value')

            if (!val) throw new Error('数据异常')

            var data = this.storeData[val]

            if (!data) throw  new Error('数据异常')

            this.value = [val]

            this.$select.find('.layui-input').val(data[this.showCol[0]])
            this.$select.find('.layui-input').data('value', [val])

            this.$element.trigger('event.checked.ptyx-api', val)

            //隐藏添加按钮
            this.$add ? this.$add.hide() : null

            if (opt.checked && typeof  opt.checked == 'function') {
                opt.checked(val)
            }

            this.$select.find('input').blur()

            this.elementSelected(val)

        } else if (this.category == 'box') {

            var val = $target.attr('lay-value')

            if (hasChecked) {
                var $li = this.$box.find('li[lay-value="' + val + '"]')
                $target.removeClass('layui-this')
                if ($li.length == 0) {
                    return
                }
                $li.remove()

                for (var i = 0; i < this.value.length; i++) {
                    if (this.value[i] == val) {
                        this.value.splice(i, 1)
                    }
                }
                this.$select.removeClass(selchecked)
                this.elementSelected(this.value)
                return
            }

            if (!val) throw new Error('数据异常')

            var data = this.storeData[val]

            if (!data) throw  new Error('数据异常')

            $target.addClass('layui-this')

            var $str = $('<li class="select2-selection__choice"><i class="layui-icon">ဆ</i><d></d><span class="num"></span></li>')
            $str.attr('lay-value', val)
            $str.find('d').text(data[this.showCol[0]])
            if (opt.theme == 'classic') {
                $str.find('span').text('(' + data[this.showCol[1]] + ')')
            }

            this.$box.find('.ptcs-select-input').before($str)

            //绑定删除事件
            $str.find('.layui-icon').on('click', $.proxy(this.deleteValueEvent, this))

            this.$box.find('input').blur()

            if ($.inArray(val, this.value) == -1) this.value.push(val)


            if (opt.checked && typeof  opt.checked == 'function') {
                opt.checked(val)
            }

            this.elementSelected(this.value)

        }

        //隐藏下拉框
        this.$select.removeClass(selchecked)

        //手动设置焦点
        this.$select.find('.layui-input').data('manuualFoucs',true)
        this.$select.find('.layui-input').focus()
    }

    //请选择事件处理(针对单选处理)
    PtyxeleSelect.prototype.optionsCheckEvent = function (e) {
        var $target = $(e.currentTarget)
        if (this.category == 'select' && !this.options.box) {
            var $check = this.$select.find('dd').not('.layui-select-tips')
            $check.removeClass('layui-this')
            this.value = []
            this.$select.find('.layui-input').val('')
            this.elementSelected('')
            this.hide()
            this.$element.trigger('event.nochecked.ptyxele-api')
        }
    }

    //输入框获取焦点事件
    PtyxeleSelect.prototype.focuseEvent = function (e) {
        var $target = $(e.currentTarget)

        if($target.data('manuualFoucs')){
            $target.data('manuualFoucs',false)
            return
        }


        var parent = '.layui-unselect.layui-form-select'

        var selected = 'layui-form-selected'

        $(parent).removeClass(selected)

        if (this.options.readonly) {
            if (!this.options.see) {
                this.show()
            }
            return
        }

        var opt = this.options
        //触发获取焦点事件
        if (opt.focusin && typeof  opt.focusin == 'function') {
            opt.focusin()
        }

        var val = ''

        if ($target.val()) {
            val = $target.val()
        }

        //去空
        val = val.replace(/^\s*|\s*$/g, "")
        this.updateSelect(val, true)
        this.show()
    }

    //输入框事件
    PtyxeleSelect.prototype.inputEvent = function (e) {

        var $target = $(e.currentTarget)

        var code = e.keyCode

        // console.info(code)

        if (/^39|37|38|40$/.test(code + '')) {
            if (/^38|40$/.test(code + '')) {
                this.focusEnd($target)
            }
            return
        }

        if (code == 13) {
            var $active = this.$select.find('dd.ptcs-this')

            if ($active.length == 0) return

            $active.trigger('click')
            return
        }

        var val = ''

        if ($target.val()) {
            val = $target.val()
        }

        val = val.replace(/^\s*|\s*$/g, "")

        if (this.options.isEnterValue && !this.options.add && !this.options.box) {
            this.value = [val]
        }

        if (code == 8 && !this.options.isEnterValue) {
            this.value = []
        }
        this.updateSelect(val, code == 8 ? false : true)
        this.show()
    }

    //下拉框上下移动
    PtyxeleSelect.prototype.selectMoveEvent = function (e) {
        var $target = $(e.currentTarget)
        var $dl = this.$select.find('dl')
        var $dd = this.$select.find('dd')

        var code = e.keyCode

        var dlH = $dl.innerHeight()
        var ddH = $dd.eq(0).outerHeight()

        if (code == 38 || code == 40) {

            if ($dd.length == 0) return

            var $active = this.$select.find('dd.ptcs-this')

            //上
            if (code == 38) {

                if ($active.length == 0) return

                var index = $active.index()

                $active.removeClass('ptcs-this')

                if (index == 0) {

                    $dd.eq($dd.length - 1).addClass('ptcs-this')
                    var top = ddH * ($dd.length)
                    $dl.scrollTop((top - dlH) + 10)
                } else {
                    $dd.eq(index - 1).addClass('ptcs-this')
                    var top = ddH * index
                    var scrollTop = $dl.scrollTop()
                    if ((top - 5) < scrollTop) {
                        $dl.scrollTop(top - ddH)
                    }
                }

                return
                //下
            } else if (code == 40) {
                var index = $active.index()
                $active.removeClass('ptcs-this')

                if ($active.length == 0) {

                    $dd.eq(0).addClass('ptcs-this')
                    return

                } else if (index == $dd.length - 1) {

                    $dd.eq(0).addClass('ptcs-this')
                    $dl.scrollTop(0)

                } else {

                    $dd.eq(index + 1).addClass('ptcs-this')

                    var top = ddH * (index + 2)
                    var scrollTop = $dl.scrollTop()
                    if ((top - dlH) > scrollTop) {
                        $dl.scrollTop((top - dlH) + 10)
                    }
                }

                return
            }
            this.focusEnd($target)
        }
    }

    //多选删除值事件
    PtyxeleSelect.prototype.deleteValueEvent = function (e) {
        var $target = $(e.currentTarget)
        var $li = $target.closest('li')
        var val = $li.attr('lay-value')
        $li.remove()
        if (!val) {
            return
        }

        for (var i = 0; i < this.value.length; i++) {
            if (this.value[i] == val) {
                this.value.splice(i, 1)
            }
        }
    }

    //把焦点位置设置末尾
    PtyxeleSelect.prototype.focusEnd = function (self) {

        var len = $(self).val().length

        if (len == 0) return this

        input = $(self)[0]

        if (input.createTextRange) {

            var range = input.createTextRange()
            range.collapse(true)
            range.moveEnd('character', len)
            range.moveStart('character', len)
            range.select()

        } else if (input.setSelectionRange) {

            input.focus()
            input.setSelectionRange(len, len)
        }
    }

    //获取下拉框值
    PtyxeleSelect.prototype.val = function (value) {
        if (value == undefined || value == null) {
            var values = ''
            for (var i = 0; i < this.value.length; i++) {
                values += ',' + this.value[i]
            }
            if (values) {
                values = values.substring(1)
            }
            return values
        }

        var $check = this.$select.find('dd.layui-this').not('.layui-select-tips')

        $check.trigger('click')

        if (this.category == 'box') {
            var $li = this.$box.find('li').not('.ptcs-select-input')
            $li.remove()
        }

        if (typeof value == 'number') {
            this.value = [value + '']
        } else if (typeof value == 'string') {
            this.value = value.split(',')
        } else if (value instanceof Array) {
            var arr = new Array()
            for (var i = 0; i < value.length; i++) {
                arr.push(value[i] + '')
            }
            this.value = arr
        } else {
            this.value = []
        }

        this.initDefaultValue()

        return this.$element
    }

    function Plugin(options) {

        return this.each(function () {
            var $this = $(this)

            var data = $this.data(PtyxeleSelect.PACE)

            Ptyxele()

            if (!data) {

                var dd = $.extend(true, PtyxeleSelect.prototype, Ptyxele.prototype, PtyxeleSelect.prototype)

                $this.data(PtyxeleSelect.PACE, (data = new dd.constructor(this, options)))
            }
        })

    }

    function SelectValue(value) {

        var $this = $(this)

        var data = $this.data(PtyxeleSelect.PACE)
        if (data) {
            return data.val(value)
        } else {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }
    }

    //设置清除缓存
    function SelectValue(value) {

        var $this = $(this)

        var data = $this.data(PtyxeleSelect.PACE)
        if (data) {
            return data.val(value)
        } else {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }
    }

    function InputValue() {

        var $this = $(this)

        var data = $this.data(PtyxeleSelect.PACE)
        if (data) {
            return data.$select.find('.layui-input').val()
        }
        return null
    }

    function PtyxeleSel() {

        var $this = $(this)

        var data = $this.data(PtyxeleSelect.PACE)
        if (data) {
            return data
        }
        return null
    }

    var oldVal = $.fn.val

    $.fn.ptyxeleSelect = Plugin

    $.fn.ptyxeleSelClearCache =

        $.fn.val = SelectValue
    $.fn.inputVal = InputValue

    $.fn.ptyxele = PtyxeleSel

    var apis = ''
    var apiAttr = ''

    $.each(PtyxeleSelect.MODULE, function (k, v) {
        apiAttr += ',[ptyx-' + k + '],[ptyx-data*="module:' + k + '"]'
        apis += ' create.' + k + '.ptyxele-api'
    })

    $(window).on('load', function () {
        $(apiAttr.substring(1)).each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxeleSelect()
        })
    })

    $(document).on(apis.substring(1), apiAttr.substring(1), function () {
        $(this).ptyxeleSelect()
    })


}(jQuery);

/**
 * Created by chenzp on 18-3-5.
 */
+function ($) {

    var PtyxeleSelectTree = function (ele, options) {
        this.$element = $(ele)

        this.options = $.extend({}, PtyxeleSelectTree.DEFAULTS)

        this.id = PtyxeleSelectTree.ID_PREFIX + new Date().getTime() + '_'

        this.init()
    }


    PtyxeleSelectTree.MODULE = {
        classify: 'classify'
        , tree: 'tree'
    }

    //空间地址
    PtyxeleSelectTree.PACE = 'ptyx.tree'

    //节点树id前缀
    PtyxeleSelectTree.ID_PREFIX = 'ptyxeleTreeNode'

    //节点缓存空间路径
    PtyxeleSelectTree.NODE_PACE = 'ptyx.tree.node'


    PtyxeleSelectTree.DEFAULTS = {
        /**
         * 相关树形业务组件 classify:商品分类
         */
        mudule: ''
        /**
         * 设置选中值字段，默认为：id
         */
        , cvalue: 'id'
        /**
         * 要显示字段，默认为name
         */
        , cshow: 'name'
        /**
         * 父类字段，默认为parentId
         */
        , cparent: 'pid'
        /**
         * 层级字段，默认为：level
         */
        , clevel: 'level'
        /**
         * 数据
         */
        , data: []
        /**
         * 值
         */
        , value: null
        /**
         * 是否可以查询
         */
        , readonly: false

        /**
         * 选中节点，默认是叶节点,反之亦然
         */
        , checkLeaf: true

        /**
         * 是否展开，默认为：展开
         */
        , unfold: true

        /**
         * 是否懒加载  默认不懒加载
         */
        , lazyload: false

        /**
         * 请求地址 如果懒加载是打开的url为必填
         */
        // , url: ''

        /**
         * 重写请求数据
         *  requestData:function (data) {
         * }
         * @param data
         */
        , requestData: null

        /**
         * 响应数据处理
         * responseData:function (res) {
         * }
         *
         */
        , responseData: null

    }

    PtyxeleSelectTree.prototype.init = function () {
        // var data = [
        //      //一级
        //      {id: 1,name: '平台系统'}
        //
        //      //二级
        //     ,{id: 2,pid:1,name: '用户管理'}
        //     ,{id: 3,pid:1,name: '商品管理'}
        //     ,{id: 4,pid:1,name: '订单管理'}
        //     ,{id: 5,pid:1,name: '集团管理'}
        //     ,{id: 6,pid:1,name: '积分管理'}
        //     ,{id: 7,pid:1,name: '财务管理'}
        //     ,{id: 8,pid:1,name: '数据管理'}
        //     ,{id: 9,pid:1,name: '页面管理'}
        //
        //     //三级-用户管理
        //     ,{id: 10,pid:2,name: '采购商管理'}
        //     ,{id: 11,pid:2,name: '供应商管理'}
        //
        //     //四级-用户管理
        //     ,{id: 46,pid:10,name: '医院资料'}
        //     ,{id: 47,pid:10,name: '账户信息'}
        //     ,{id: 48,pid:10,name: '修改密码'}
        //     ,{id: 49,pid:11,name: '账户信息'}
        //     ,{id: 50,pid:12,name: '店铺信息'}
        //     ,{id: 51,pid:12,name: '销售信息'}
        //
        //
        //     //三级-商品管理
        //     ,{id: 12,pid:3,name: '商品列表'}
        //     ,{id: 13,pid:3,name: '产品管理'}
        //     ,{id: 14,pid:3,name: '分类管理'}
        //
        //     //四级-商品管理
        //     ,{id: 52,pid:12,name: '编辑商品'}
        //     ,{id: 53,pid:12,name: '新增商品'}
        //     ,{id: 54,pid:12,name: '删除商品'}
        //     ,{id: 55,pid:13,name: '添加产品'}
        //     ,{id: 56,pid:13,name: '删除产品'}
        //     ,{id: 57,pid:13,name: '更新产品'}
        //     ,{id: 57,pid:14,name: '修改类目'}
        //     ,{id: 58,pid:14,name: '新增类目'}
        //     ,{id: 60,pid:14,name: '删除类目'}
        //
        //
        //
        //
        //     //三级-订单管理
        //     ,{id: 15,pid:4,name: '所有订单'}
        //     ,{id: 16,pid:4,name: '退货管理'}
        //     ,{id: 17,pid:4,name: '评价管理'}
        //     ,{id: 18,pid:4,name: '快速采购'}
        //
        //
        //     //四级-订单管理
        //     ,{id: 61,pid:15,name: '订单列表'}
        //     ,{id: 62,pid:15,name: '订单详情'}
        //     ,{id: 63,pid:15,name: '订单审核'}
        //     ,{id: 64,pid:16,name: '退款明细'}
        //     ,{id: 65,pid:17,name: '店铺评价'}
        //     ,{id: 66,pid:17,name: '商品评价'}
        //     ,{id: 67,pid:17,name: '物流评价'}
        //     ,{id: 68,pid:17,name: '服务评价'}
        //     ,{id: 69,pid:18,name: '历史采购'}
        //     ,{id: 70,pid:18,name: '商品明细'}
        //
        //
        //
        //     //三级-集团管理
        //     ,{id: 19,pid:5,name: '采购目录'}
        //     ,{id: 20,pid:5,name: '入库计划'}
        //     ,{id: 21,pid:5,name: '医院报表'}
        //
        //     //四级-集团管理
        //     ,{id: 71,pid:19,name: '明细'}
        //     ,{id: 72,pid:19,name: '目录修改'}
        //     ,{id: 73,pid:19,name: '新增目录'}
        //     ,{id: 74,pid:20,name: '新增入库'}
        //     ,{id: 75,pid:20,name: '修改入库'}
        //     ,{id: 76,pid:20,name: '删除入库'}
        //     ,{id: 77,pid:21,name: '供应商报表'}
        //     ,{id: 78,pid:21,name: '采购商报表'}
        //     ,{id: 79,pid:21,name: '对账信息'}
        //
        //     //三级-积分管理
        //     ,{id: 22,pid:6,name: '积分账户'}
        //     ,{id: 23,pid:6,name: '积分明细'}
        //     ,{id: 24,pid:6,name: '积分订单'}
        //     ,{id: 25,pid:6,name: '商品分类'}
        //     ,{id: 26,pid:6,name: '积分商家'}
        //
        //     //三级-财务管理
        //     ,{id: 27,pid:7,name: '普天宝'}
        //     ,{id: 28,pid:7,name: '普天白条'}
        //     ,{id: 29,pid:7,name: '退款管理'}
        //     ,{id: 30,pid:7,name: '收款管理'}
        //     ,{id: 31,pid:7,name: '结算管理'}
        //     ,{id: 32,pid:7,name: '收支明细'}
        //
        //     //三级-数据管理
        //     ,{id: 33,pid:8,name: '平台用户数据'}
        //     ,{id: 34,pid:8,name: '订单采购数据'}
        //     ,{id: 35,pid:8,name: '订单销售数据'}
        //     ,{id: 36,pid:8,name: '订单地区数据'}
        //     ,{id: 37,pid:8,name: '商品分类数据'}
        //     ,{id: 38,pid:8,name: '商品采购数据'}
        //     ,{id: 39,pid:8,name: '订单支付数据'}
        //
        //     //三级-页面管理
        //     ,{id: 40,pid:9,name: '轮播图片'}
        //     ,{id: 41,pid:9,name: '畅销商品'}
        //     ,{id: 42,pid:9,name: '畅销品牌'}
        //     ,{id: 43,pid:9,name: '普天公告'}
        //     ,{id: 44,pid:9,name: '普天之声'}
        //     ,{id: 45,pid:9,name: '友情链接'}
        //
        // ];
        this.mergeOption()
        this.initData()
        this.createSelectDiv()
        this.addData(this.options.data)
        this.resetDraw(true)
        this.initEvent()
        this.val(this.value)
    }


    PtyxeleSelectTree.prototype.initEvent = function () {
        var $this = this
        var opt = this.options
        // $(document).on('click', function (e) {
        //     var $target = $(e.target)
        //     var select = '.layui-unselect'
        //     var $parent = $target.closest(select)
        //     if ($parent.length > 0) {
        //         return
        //     } else {
        //         var val = $this.value
        //
        //         if (val) {
        //             $this.hideFilter()
        //             var ele = $this.store[val]
        //             $this.$input.val(ele[opt.cshow])
        //         }
        //         $this.hide()
        //     }
        // })
    }

    //渲染数据
    PtyxeleSelectTree.prototype.drawData = function (id, isLoaded) {
        if (!id) return

        var opt = this.options

        if (!this.store[id]) throw new Error('数据异常')

        var pid = this.store[id][opt.cparent]

        if (!this.store[pid]) throw new Error('数据异常')

        var prefix = '#' + this.id
        var $parent = this.$ul.find(prefix + pid)

        if ($parent.length == 0) throw new Error('数据异常')

        var ele = this.store[id]
        var node = PtyxeleSelectTree.NODE_PACE
        var cacheData = $parent.data(node)

        //清除已经存在的
        this.$select.find(prefix + id).remove()

        var $li = $('<li><span class="xing"><a></a><span class="num">0</span></span></li>')
        $li.find('.xing').on('click', $.proxy(this.checkedEvent, this))
        $li.on('mouseover', $.proxy(this.hoverAutoEvent, this))


        $li.attr({id: this.id + id}).find('a').text(ele[opt.cshow])
        $li.data(node, {id: id, child: [], pid: pid, loaded: isLoaded ? true : false})

        if (!$parent.hasClass('folder')) {
            $parent.addClass('folder')
            if ($parent.find('.num').length == 0) {
                $parent.find('.xing').append('<span class="num">1</span>')
            }

            if ($parent.find('i').length == 0) {
                $parent.prepend('<i class="layui-icon">&#xe623;</i>')
            }

            //添加事件
            $parent.find('i').on('click', $.proxy(this.unfoldEvent, this))

            var $ul = $('<ul></ul>')
            $ul.hide()
            $parent.after($ul)
            cacheData.$ul = $ul
            var caData = new Object()
            caData[id] = []
            cacheData.child.push(caData)
            $ul.append($li)
        } else {
            var $ul = cacheData.$ul
            $ul.append($li)
            var caData = new Object()
            caData[id] = []
            cacheData.child.push(caData)
            $parent.find('.num').text(cacheData.child.length)
        }
    }

    //重新渲染
    PtyxeleSelectTree.prototype.resetDraw = function (isInit) {
        if (!this.treeData) return


        var $this = this
        var opt = this.options
        var idObj = this.store

        function draw(ul, data) {
            var $pul = $(ul)

            for (index in data) {
                var arrEle = data[index]

                var child = []
                var blObj = new Object()
                if (data instanceof Array) {

                    blObj = arrEle
                } else {
                    blObj[index] = arrEle
                }

                for (dd in blObj) {
                    var ele = idObj[dd]
                    var dchild = blObj[dd]

                    if (!ele) {
                        return draw($pul, dchild)

                    }

                    var $li = $(li)

                    $li.find('.xing').on('click', $.proxy($this.checkedEvent, $this))

                    $li.on('mouseover', $.proxy($this.hoverAutoEvent, $this))

                    $li.attr({id: pre + dd}).find('a').text(ele[opt.cshow])

                    var isload = opt.lazyload ? false : true

                    if (dchild.length > 0) {
                        var $$ul = $('<ul></ul>')
                        $li.addClass('folder').data(node, {
                            id: dd,
                            child: dchild,
                            pid: ele[opt.cparent],
                            $ul: $$ul,
                            loaded: isload
                        })
                        var $num = $(num)

                        var childNum = 0

                        for (cnum in dchild[0]) {
                            childNum++
                        }

                        $num.text(childNum)
                        $li.find('.xing').append($num)
                        $pul.append($li)
                        $$ul.hide()
                        $li.prepend('<i class="layui-icon">&#xe623;</i>')
                        $li.after($$ul)

                        //添加事件
                        $li.find('i').on('click', $.proxy($this.unfoldEvent, $this))

                        draw($$ul, dchild)
                    } else {

                        $li.data(node, {id: dd, child: [], pid: ele[opt.cparent], loaded: isload})
                        $li.find('.xing').append($(num))

                        if (isInit && !isload) {
                            $li.prepend('<i class="layui-icon">&#xe623;</i>')
                        }

                        $pul.append($li)
                    }
                }
            }
        }


        var $ul = this.$ul
        $ul.empty()

        var li = '<li><span class="xing"><a></a></span></li>'
        var num = '<span class="num">0</span>'
        var node = PtyxeleSelectTree.NODE_PACE
        var prefix = '#' + this.id
        var pre = this.id

        draw($ul, this.treeData)

    }

    //加载数据
    PtyxeleSelectTree.prototype.loadData = function (data) {
        if (!data) return

        var $this = this
        var opt = this.options


        if (!opt.url) throw  new Error('地址不能为空')

        var loadedId = new Array()


        function reload(value, storeData) {

            var serData = new Object()

            if (value instanceof Array) {
                $.unique(value);
            }

            serData[opt.cvalue] = value

            if (typeof opt.requestData == 'function') {
                serData = opt.requestData(serData)
            } else {

                if (value instanceof Array) {
                    var ids = ''
                    for (var i = 0; i < value.length; i++) {
                        ids += ',' + value[i]
                    }

                    if (ids) {
                        ids = ids.substring(1)
                    }

                    serData[opt.cvalue] = ids
                }

            }

            if (!serData) {
                throw new Error('请求数据不能为空')
            }

            var reloadPids = new Array()

            var resArr = new Array()

            $.ajax({
                data: serData
                , url: opt.url
                , async: false
                , dataType: 'json'
                , success: function (res) {

                    var resData = new Object()

                    if (typeof opt.responseData == 'function') {
                        resData = opt.responseData(res)
                    } else {
                        if (!res.successful) {
                            if (rs.msg) {
                                throw new Error(res.msg)
                            }
                            throw new Error('数据请求失败')
                        } else {
                            if (res.result) {
                                resData = res.result
                            }
                        }
                    }


                    if (!resData) throw new Error('数据不能为空')


                    if (resData instanceof Array) {
                        resArr = resData
                    } else {
                        resArr.push(resData)
                    }

                    loadedId.push(value + '')
                }
                , error: function (e) {
                    isOver = true
                    console.info('数据请求失败')
                    console.info(e)
                }

            })


            for (var i = 0; i < resArr.length; i++) {
                var ele = resArr[i]
                if (!ele[opt.cparent]) {
                    storeData.splice(0, 0, ele)
                } else {
                    if (!$this.store[ele[opt.cparent]]) {
                        reloadPids.push(ele[opt.cparent])
                    }
                    storeData.splice(0, 0, ele)
                }
            }

            if (reloadPids.length == 0) {
                return storeData
            } else {
                return reload(reloadPids, storeData)
            }

        }

        var reloadData = reload(data, new Array())


        if (!reloadData) return

        if (reloadData.length > 0) {
            this.addData(reloadData)
        }


        for (var i = 0; i < reloadData.length; i++) {
            this.drawData(reloadData[i][opt.cvalue], false)
        }
        for (var i = 0; i < loadedId.length; i++) {
            var id = loadedId[i]

            var $id = this.$select.find('#' + this.id + id)

            var nodeData = $id.data(PtyxeleSelectTree.NODE_PACE)

            if (nodeData) {
                nodeData.loaded = true
            } else {
                $id.data(PtyxeleSelectTree.NODE_PACE, {loaded: true})
            }

        }

    }

    //懒加载数据
    PtyxeleSelectTree.prototype.lazyloadData = function (data) {

        var $this = this
        var opt = this.options

        var serData = new Object()

        serData[opt.cparent] = data

        if (typeof opt.requestData == 'function') {
            serData = opt.requestData(serData)
        }

        if (!serData) {
            throw new Error('请求数据不能为空')
        }


        $.ajax({
            data: serData
            , url: opt.url
            // ,async:false
            , dataType: 'json'
            , success: function (res) {

                var resData = new Object()

                if (typeof opt.responseData == 'function') {
                    resData = opt.responseData(res)
                } else {
                    if (!res.successful) {
                        if (rs.msg) {
                            throw new Error(res.msg)
                        }
                        throw new Error('数据请求失败')
                    } else {
                        if (res.result) {
                            resData = res.result
                        }
                    }
                }

                if (!resData) throw new Error('数据不能为空')

                $this.addData(resData)

                for (var i = 0; i < resData.length; i++) {
                    var ele = resData[i]
                    $this.drawData(ele[opt.cvalue], false)
                }

            }
            , error: function (e) {
                isOver = true
                console.info('数据请求失败')
                console.info(e)
            }

        })
    }

    //查询树形数据
    PtyxeleSelectTree.prototype.search = function (word) {

        word = word.replace(/^\s*|\s*$/g, "")

        if (!word) {
            this.hideFilter()
            return
        }

        //如果开启服务端查询以本地查询
        var $this = this
        var opt = this.options
        var prefix = '#' + this.id

        var cache = this.cache

        if (!cache) {
            this.cache = new Object()
            cache = this.cache
        }

        //缓存提起数据
        var arr = cache[word]
        if (arr) {
            var sindex = arr.length > 0 ? 1 : 0
            this.showFilter(sindex, arr.length)
            this.searchData = {data: arr, index: sindex}

            if (arr.length > 0) {
                this.positionNode(arr[0][opt.cvalue])

                var $tag = this.$select.find(prefix + arr[0][opt.cvalue]).find('.xing')
                $tag.addClass('ptcs-tree-search')

                if (this.$tag && !$tag.is(this.$tag)) {
                    this.$tag.removeClass('ptcs-tree-search')
                }
                this.$tag = $tag

                this.$input[0].focus()
            } else {
                if (this.$tag) this.$tag.removeClass('ptcs-tree-search')
            }
            return
        }

        //本地查询
        if (!opt.lazyload || !opt.url) {
            if (!this.store) {
                this.showFilter(0, 0)
                return
            }

            var sdata = new Array()

            for (id in this.store) {
                var ele = this.store[id]

                var name = ele[opt.cshow]

                if (!name) continue

                if (name.indexOf(word) != -1) {
                    sdata.push(ele)
                }

            }

            cache[word] = sdata
            var sindex = sdata.length > 0 ? 1 : 0

            this.showFilter(sindex, sdata.length)
            this.searchData = {data: sdata, index: sindex}
            if (sdata.length > 0) {
                this.positionNode(sdata[0][opt.cvalue])

                var $tag = this.$select.find(prefix + sdata[0][opt.cvalue]).find('.xing')
                $tag.addClass('ptcs-tree-search')

                if (this.$tag && !$tag.is(this.$tag)) {
                    this.$tag.removeClass('ptcs-tree-search')
                }
                this.$tag = $tag

                this.$input[0].focus()

            } else {
                if (this.$tag) this.$tag.removeClass('ptcs-tree-search')
            }
            return
        }

        //服务端查询
        var serData = new Object()

        serData[opt.cshow] = word

        if (typeof opt.requestData == 'function') {
            serData = opt.requestData(serData)
        }

        if (!serData) {
            throw new Error('请求数据不能为空')
        }

        $.ajax({
            data: serData
            , url: opt.url
            , dataType: 'json'
            , success: function (res) {
                var resData = new Object()

                if (typeof opt.responseData == 'function') {
                    resData = opt.responseData(res)
                } else {
                    if (!res.successful) {
                        if (rs.msg) {
                            throw new Error(res.msg)
                        }
                        throw new Error('数据请求失败')
                    } else {
                        if (res.result) {
                            resData = res.result
                        }
                    }
                }


                if (!resData) return

                var resArr = new Array()

                if (resData instanceof Array) {
                    resArr = resData
                } else {
                    resArr.push(resData)
                }

                var sindex = resArr.length > 0 ? 1 : 0

                $this.cache[word] = resArr
                $this.showFilter(sindex, resArr.length)
                $this.searchData = {data: resArr, index: sindex}

                if (resArr.length > 0) {
                    $this.positionNode(resArr[0][opt.cvalue])


                    var $tag = $this.$select.find(prefix + resArr[0][opt.cvalue]).find('.xing')
                    $tag.addClass('ptcs-tree-search')

                    if ($this.$tag && !$tag.is($this.$tag)) {
                        $this.$tag.removeClass('ptcs-tree-search')
                    }
                    $this.$tag = $tag

                    $this.$input[0].focus()
                } else {
                    if ($this.$tag) $this.$tag.removeClass('ptcs-tree-search')
                }
            }
            , error: function (e) {
                console.info('数据请求失败')
                console.info(e)
            }
        })

    }

    // 解析数据
    PtyxeleSelectTree.prototype.addData = function (data) {
        if (!data) return

        var opt = this.options

        var idObj = this.store ? this.store : new Object()

        var idPid = this.idPid

        if (!idPid) {
            idPid = new Object()
            this.idPid = idPid
        }

        var treeData = this.treeData ? this.treeData : new Object()

        function getArr(pid, sObj) {
            var obj = new Object()
            var ppid = idPid[pid]

            if (ppid != undefined && ppid != null) {
                // if (ppid) {
                delete copyIdPid[pid]
                if (sObj[pid]) {
                    obj[ppid] = [sObj]
                    return getArr(ppid, obj)
                } else {
                    var oo = new Object()
                    oo[pid] = []
                    obj[ppid] = [oo]
                    return getArr(ppid, obj)
                }
            } else {
                return sObj
            }
        }

        //数组
        if (data instanceof Array) {

            // var stime = new Date().getTime()
            var changeData = new Object()
            for (index in data) {
                var ele = data[index]
                idPid[ele[opt.cvalue]] = ele[opt.cparent]
                changeData[ele[opt.cvalue]] = ele[opt.cparent]
                idObj[ele[opt.cvalue]] = ele
            }

            var copyIdPid = changeData


            for (id in copyIdPid) {
                var eleObj = getArr(id, {})
                $.extend(true, treeData, eleObj)
            }
            // var etime = new Date().getTime()
            // console.info((etime - stime)+'ms')
            // console.info(JSON.stringify(treeData))
        }
        this.treeData = treeData
        this.store = idObj

    }

    //定位节点
    PtyxeleSelectTree.prototype.positionNode = function (id) {
        var node = PtyxeleSelectTree.NODE_PACE
        var prexfix = '#' + this.id
        var $this = this

        if (this.options.lazyload && this.options.url) {
            this.loadData(id)
        }

        function showParentNode(id) {
            var $node = $this.$select.find(prexfix + id)
            if ($node.length == 0) return

            var nodeData = $node.data(node)

            if (!nodeData) return

            if ($node.hasClass('folder') && !$node.hasClass('open')) {
                $node.addClass('open')
                $node.find('i').html('&#xe625;')
                nodeData.$ul.show()
            }


            var pid = nodeData.pid

            if (!pid) return

            return showParentNode(pid)

        }

        showParentNode(id)

        location.href = prexfix + id
    }

    //上下查询搜索节点事件
    PtyxeleSelectTree.prototype.moveSearchEvent = function (e) {
        var $target = $(e.currentTarget)

        var searchData = this.searchData
        var opt = this.options

        if (!searchData && this.$tag) {
            this.$tag.removeClass('ptcs-tree-search')
        }

        var arr = searchData.data
        var index = searchData.index
        var prexfix = '#' + this.id


        //向上
        if ($target.is(this.$sup)) {
            if (index == 1) return
            index = index - 1
        } else {
            if (index == arr.length) return
            index = index + 1
        }

        var id = arr[index - 1][opt.cvalue]


        this.searchData.index = index

        this.showFilter(index, arr.length)

        this.positionNode(id)

        var $tag = $(prexfix + id).find('.xing')
        $tag.addClass('ptcs-tree-search')

        if (this.$tag && !$tag.is(this.$tag)) {
            this.$tag.removeClass('ptcs-tree-search')
        }
        this.$tag = $tag

        this.$input[0].focus()

    }

    //创建下拉框
    PtyxeleSelectTree.prototype.createSelectDiv = function () {
        var $this = this
        var opt = this.options
        this.$element.hide()

        var str = '<div class="layui-unselect layui-form-select">' +
            '        <input type="text"  autocomplete="off" class="layui-input">' +
            '        <div class="st_result ptcs-tree-opt">' +
            '            <span class="location ptcs-tree-location"></span>' +
            '            <span class="num ptcs-tree-snum"><span>14</span>/<span>40</span></span>' +
            '            <i class="layui-icon ptcs-tree-up"title="上一个">&#xe619;</i>' +
            '            <i class="layui-icon ptcs-tree-down" title="下一个">&#xe61a;</i>' +
            '        </div>' +
            '        <div class="st_tree">' +
            '            <div class="shrink_expand">' +
            // '                <button class="left_btn">全部展开</button>' +
            '            </div>' +
            '       <div class="ant_st_tree">' +
            '            <ul>' +
            '            </ul>' +
            '        </div>' +
            '        </div>' +
            '    </div>'


        var $str = $(str)

        this.$select = $str
        this.$position = $str.find('.ptcs-tree-location')
        this.$sum = $str.find('.ptcs-tree-snum')
        this.$sup = $str.find('.ptcs-tree-up')
        this.$sdown = $str.find('.ptcs-tree-down')
        this.$input = $str.find('input')
        this.$ul = $str.find('ul')

        //判断是否要开启添加按钮
        if (opt.add == true) {
            var $add = $('<div class="ant_select_fast"><span><i class="layui-icon layui-icon-add-1">&#xe654;</i>新增</span></div>')
            $str.find('.ant_st_tree').after($add)
            $add.click(function () {
                $this.$element.trigger('event.tree.add.ptyxele-api', $this)
            })
        }

        if (opt.readonly) {
            this.$input.attr('readonly', true)
        } else {
            //输入框事件  焦点
            this.$input.on('keyup', $.proxy(this.inputEvent, this))
        }

        var $this = this
        this.$input.on('focusin click', function () {
            $this.show()
        })


        this.$sup.on('click', $.proxy(this.moveSearchEvent, this))
        this.$sdown.on('click', $.proxy(this.moveSearchEvent, this))

        //定位事件
        this.$position.on('click', function () {
            if ($this.value) {
                $this.show()
                $this.positionNode($this.value)
            }
        })

        this.$element.after($str)
        this.hideFilter()
        this.hide()
    }

    //显示筛选
    PtyxeleSelectTree.prototype.showFilter = function (index, total) {
        this.$position.hide()

        this.$sum.show()
        this.$sup.show()
        this.$sdown.show()
        if (typeof index == 'number' && index >= 0) {
            this.$sum.find('span:eq(0)').text(index)
        }

        if (typeof total == 'number' && total >= 0) {
            this.$sum.find('span:eq(1)').text(total)
        }
    }

    //隐藏筛选
    PtyxeleSelectTree.prototype.hideFilter = function () {
        this.$position.show()
        this.$sum.hide()
        this.$sup.hide()
        this.$sdown.hide()
    }

    //显示下拉框
    PtyxeleSelectTree.prototype.show = function () {
        var selected = 'layui-form-selected'
        this.$select.addClass(selected)
        this.$select.find('.st_tree').show()

    }

    //隐藏下拉框
    PtyxeleSelectTree.prototype.hide = function () {
        var selected = 'layui-form-selected'
        this.$select.removeClass(selected)
        this.$select.find('.st_tree').hide()

    }

    //展开与收起事件
    PtyxeleSelectTree.prototype.unfoldEvent = function (e) {
        var $target = $(e.currentTarget)
        var $parent = $target.closest('li')

        if (!$parent.hasClass('folder')) return

        var isOpen = $parent.hasClass('open')
        var node = PtyxeleSelectTree.NODE_PACE
        var data = $parent.data(node)

        if (data.$ul.length == 0) return


        // $parent.find('i').on('click',$.proxy(this.unfoldEvent))

        var opt = this.options

        if (opt.lazyload) {
            var $lis = data.$ul.find('li')

            var ids = ''

            for (var i = 0; i < $lis.length; i++) {
                var $cli = $lis.eq(i)
                var childData = $cli.data(node)

                if (childData.loaded) continue

                //标记为已下载
                childData.loaded = true
                ids += ',' + childData.id
            }

            if (ids) {
                ids = ids.substring(1)
                this.lazyloadData(ids)
            }
        }

        if (isOpen) {
            $parent.removeClass('open')
            $parent.find('i').html('&#xe623;')
            // $parent.prepend('<i class="layui-icon">&#xe623;</i>')
            data.$ul.hide()
        } else {
            $parent.addClass('open')
            $parent.find('i').html('&#xe625;')
            // $parent.prepend('<i class="layui-icon">&#xe625;</i>')
            data.$ul.show()
        }


    }

    //输入框事件
    PtyxeleSelectTree.prototype.inputEvent = function (e) {
        var $target = $(e.currentTarget)
        var val = $target.val()

        val = val.replace(/^\s*|\s*$/g, '')

        this.search(val)
    }

    //鼠标移进来触发自动查询子节点数据
    PtyxeleSelectTree.prototype.hoverAutoEvent = function (e) {
        var $target = $(e.currentTarget)
        var ele = $target.data(PtyxeleSelectTree.NODE_PACE)
        if (!ele.loaded) {
            //标记为已下载
            ele.loaded = true
            this.lazyloadData(ele.id)
        }
    }

    //选中值
    PtyxeleSelectTree.prototype.checkedEvent = function (e) {
        var $target = $(e.currentTarget)
        var $parent = $target.closest('li')
        var opt = this.options
        var ele = $parent.data(PtyxeleSelectTree.NODE_PACE)

        if (opt.checkLeaf) {

            if (opt.lazyload && opt.url) {
                if (!ele.loaded) {
                    this.loadData(ele.id)
                }
                ele = $parent.data(PtyxeleSelectTree.NODE_PACE)

                if (ele.child.length > 0) return
            } else {
                if (ele.child.length > 0) return
            }
        }

        if (this.$checked) this.$checked.removeClass('checked')

        $target.addClass('checked')

        var data = this.store[ele.id]

        this.$checked = $target
        this.$input.val(data[opt.cshow])
        this.value = ele.id

        var $option = $('<option value="' + ele.id + '" selected></option>')
        this.$element.append($option)
        $option.prop('selected', true)


        // 清除查询数据
        if (this.$tag) {
            this.$tag.removeClass('ptcs-tree-search')
        }
        this.$tag = null
        this.hideFilter()

        this.hide()
    }

    //初始加载数据
    PtyxeleSelectTree.prototype.initData = function () {
        var opt = this.options

        if (!opt.url) {
            return
        }

        var serData = new Object()

        if (opt.lazyload) {
            serData[opt.cparent] = 0
        }

        if (typeof opt.requestData == 'function') {
            serData = opt.requestData(serData)
        }

        $.ajax({
            url: opt.url
            , dataType: 'json'
            , async: false
            , data: serData
            , success: function (res) {
                var resData = new Object()

                if (typeof opt.responseData == 'function') {
                    resData = opt.responseData(res)
                } else {
                    if (!res.successful) {
                        if (res.msg) {
                            throw new Error(res.msg)
                        }
                        throw new Error('数据请求失败')
                    } else {
                        if (res.result) {
                            resData = res.result
                        }
                    }
                }
                opt.data = opt.data.concat(resData)
            }
            , error: function (e) {
                console.info(e)
            }
        })


    }

    //赋值或修改值
    PtyxeleSelectTree.prototype.val = function (value) {
        if (value == undefined || value == null) {
            if (this.value) {
                return this.value + ''
            } else {
                return null
            }
        }

        var opt = this.options
        var node = '#' + this.id


        if (!this.store || (this.store && !this.store[value])) {
            if (!opt.url) return
            this.loadData(value)
        }

        if (opt.checkLeaf) {
            var data = $(node + value).data(PtyxeleSelectTree.NODE_PACE)
            if (data.child.length > 0) throw new Error('选中的节点是非叶节点')
        }

        if (this.$checked && this.$checked.length > 0) {
            this.$checked.removeClass('checked')
        }
        var $id = $(node + value)
        $id.find('.xing').addClass('checked')
        this.$checked = $id.find('.xing')

        var ele = this.store[value]
        this.value = value
        this.$input.val(ele[opt.cshow])

        var $option = $('<option value="' + value + '" selected></option>')
        this.$element.append($option)
        $option.prop('selected', true)

        this.positionNode(value)
    }

    var oldVal = $.fn.val


    function Plugin(options) {
        return this.each(function () {
            var $this = $(this)

            var data = $this.data(PtyxeleSelectTree.PACE)

            Ptyxele()

            if (!data) {

                var dd = $.extend(true, PtyxeleSelectTree.prototype, Ptyxele.prototype, PtyxeleSelectTree.prototype)

                $this.data(PtyxeleSelectTree.PACE, (data = new dd.constructor(this, options)))
            }
        })
    }

    function SelectValue(value) {

        var $this = $(this), data = $this.data(Ptyxele.PTYXELE)

        if (!data) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }

        var module = data.module.replace(Ptyxele.ID_PREFIX, '')

        if (!PtyxeleSelectTree.MODULE[module]) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        } else {
            data = $this.data(PtyxeleSelectTree.PACE)
            if (data) {
                return data.val(value)
            } else {
                $this.ptyxeleTree()
                data = $this.data(PtyxeleSelectTree.PACE)
                return data.val(value)
                // return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
            }
        }
    }

    function TreeReset(value) {

        var $this = $(this)

        data = $this.data(PtyxeleSelectTree.PACE)

        if (data) {
            data.treeData = null
            data.store = null
            data.initData()
            data.addData(data.options.data)
            data.resetDraw(true)
        }

    }

    $.fn.ptyxeleTree = Plugin
    $.fn.val = SelectValue
    $.fn.treeReset = TreeReset


    $(window).on('load', function () {
        $('select[ptyx-tree],select[ptyx-classify]').each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxeleTree()
        })
    })

}(jQuery);

/**
 * Created by chenzp on 18-3-31.
 */
+function ($) {

    var PtyxeleVerify = function (element) {
        this.$element = $(element)
        this.init()
    }

    PtyxeleVerify.VERIFY = {

        //非空验证
        required: {
            reg: function (value) {

                if (value == null || value == undefined) return false

                value = value.replace(/^\s*|\s*$/g, '')

                return /[\S]+/.test(value)
            }
            , msg: '必填项不能为空'
        }

        //手机号码验证
        , phone: {
            reg: /^1\d{10}$/
            , msg: '请输入正确的手机号'
        }

        //email验证
        , email: {
            reg: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
            , msg: '邮箱格式不正确'
        }

        //链接地址验证
        , url: {
            reg: /(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/
            , msg: '链接格式不正确'
        }

        //数值验证
        , number: {
            reg: function (e) {
                if (!e || isNaN(e)) return false
                return true
            }
            , msg: '只能填写数字'
        }

        //日期验证
        , date: {
            reg: /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/
            , msg: '日期格式不正确'
        }

        //简单身份证验证
        , identity: {
            reg: /(^\d{15}$)|(^\d{17}(x|X|\d)$)/
            , msg: '请输入正确的身份证号'
        }

        //汉字验证
        , character: {
            reg: /^[\u4e00-\u9fa5]{0,}$/
            , msg: '请输入汉字'
        }

        //字母验证

        , char: {
            reg: /^[a-zA-Z]*$/
            , msg: '请输入字母'
        }

        //整数验证
        , int: {
            reg: /^0$|^[1-9]\d*$/
            , msg: '请输入整数'
        }

        //数字和字母验证
        , charNum: {
            reg: /^0$|^[1-9]\d*$/
            , msg: '请输入字母和数字'
        }

        //高级身份证验证
        , identityReal: {
            reg: function (code) {
                var city = {
                    11: "北京",
                    12: "天津",
                    13: "河北",
                    14: "山西",
                    15: "内蒙古",
                    21: "辽宁",
                    22: "吉林",
                    23: "黑龙江 ",
                    31: "上海",
                    32: "江苏",
                    33: "浙江",
                    34: "安徽",
                    35: "福建",
                    36: "江西",
                    37: "山东",
                    41: "河南",
                    42: "湖北 ",
                    43: "湖南",
                    44: "广东",
                    45: "广西",
                    46: "海南",
                    50: "重庆",
                    51: "四川",
                    52: "贵州",
                    53: "云南",
                    54: "西藏 ",
                    61: "陕西",
                    62: "甘肃",
                    63: "青海",
                    64: "宁夏",
                    65: "新疆",
                    71: "台湾",
                    81: "香港",
                    82: "澳门",
                    91: "国外 "
                }
                var tip = ""

                if (!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) {
                    tip = "身份证号格式错误"
                    return false
                }

                else if (!city[code.substr(0, 2)]) {
                    tip = "地址编码错误"
                    return false
                } else {
                    //18位身份证需要验证最后一位校验位
                    if (code.length == 18) {
                        code = code.split('')
                        //∑(ai×Wi)(mod 11)
                        //加权因子
                        var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
                        //校验位
                        var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
                        var sum = 0
                        var ai = 0
                        var wi = 0
                        for (var i = 0; i < 17; i++) {
                            ai = code[i]
                            wi = factor[i]
                            sum += ai * wi
                        }
                        var last = parity[sum % 11]
                        if (parity[sum % 11] != code[17]) {
                            tip = "校验位错误"
                            return false
                        }
                    }
                }
                return true;
            }
            , msg: '请输入正确的身份证号'
        }

        //金钱验证
        , money: {
            reg: /(^(([1-9]+[0-9]*)|([0]{1}[.]{1})|([1-9]{1}[0-9]*[.]{1})){1}[0-9]*[0-9]{1}$)|(^[1-9]+[0-9]*$)/
            , msg: '数值格式不正确'
        }

        //商品价格
        , priceNumber: {
            reg: /(^(([1-9]+[0-9]*)|([0]{1}[.]{1})|([1-9]{1}[0-9]*[.]{1})){1}[0-9]*[1-9]{1}$)|(^[1-9]+[0-9]*$)/
            , msg: '格式不正确请输入大于零的值'
        }

        //商品价格小数位4位
        , pricePointNum: {
            reg: /^\d+(?:\.\d{1,4})?$/
            , msg: '格式不正确请输入至多4位小数位的值'
        }

        //商品价格可以等于零
        , price: {
            reg: /(^[0]*$)|(^0[.]{1}[0-9]*$)|(^[0-9]*$)|(^[0]*[1-9]+[0-9]*[.]{1}[0-9]+$)/
            , msg: '数值格式不正确'
        }
        //qq号
        , qq: {
            reg: /[1-9][0-9]{4,14}/
            , msg: '请输入正确的qq号'
        }
    }

    PtyxeleVerify.PACE = 'ptyxele-verify'

    //数值比较类型
    PtyxeleVerify.COM_NUM_TYPE = 1

    //对象比较类型
    PtyxeleVerify.COM_OBJ_TYPE = 2

    //日期比较类型
    PtyxeleVerify.COM_DATE_TYPE = 3

    //普通正则表达式
    PtyxeleVerify.COMMOM_TYPE = 4

    //比较字符串长度
    PtyxeleVerify.COM_CHAR_TYPE = 5

    PtyxeleVerify.SUBMIT_STAT = 'ptyxeleFromSubmitStat'

    PtyxeleVerify.DEFAULT = {}

    //初始化标签
    PtyxeleVerify.prototype.init = function () {
        this.parseExpression()
    }

    //解析表达式
    PtyxeleVerify.prototype.parseExpression = function () {

        var exp = this.$element.attr('ptyx-verify')

        if (!exp) return

        var expstrArr = exp.split('|')

        var msgs = this.$element.attr('ptyx-verify-msg')

        var msgObj = new Object()

        if (msgs) msgObj = Ptyxele.UTIL.parseQuickAttrValueObj(msgs)


        var regArr = new Array()

        for (var i = 0; i < expstrArr.length; i++) {

            var expEle = expstrArr[i]


            var msg = msgObj[expEle] ? msgObj[expEle] : PtyxeleVerify.VERIFY[expEle] ? PtyxeleVerify.VERIFY[expEle].msg : ''

            var expObj = {reg: expEle, msg: msg}

            if (/^[=!><]{1}[-]{0,1}[0-9.]+$/.test(expEle)) {

                expObj.type = PtyxeleVerify.COM_NUM_TYPE

                if (!msg) expObj.msg = '输入的值必须满足' + expEle

            } else if (/^[=!><]{1}['"]{1}[0-9.]+['"]{1}$/.test(expEle)) {

                expObj.type = PtyxeleVerify.COM_CHAR_TYPE

                if (!msg) expObj.msg = '输入的字符串长度必须满足' + expEle

            } else if (/^[=!><]{1}[0-9a-zA-Z]+$/.test(expEle)) {

                expObj.type = PtyxeleVerify.COM_OBJ_TYPE

                if (!msg) expObj.msg = '输入的值必须满足相对其他输入框或选择框的值'

            } else if (/^[!=<>]{1}((\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*){1}$/.test(expEle)) {

                expObj.type = PtyxeleVerify.COM_DATE_TYPE

                if (!msg) expObj.msg = '输入的值必须满足' + expEle

            } else {

                expObj.type = PtyxeleVerify.COMMOM_TYPE
            }

            regArr.push(expObj)
        }

        this.reg = regArr
    }

    //正则判断
    PtyxeleVerify.prototype.verify = function (isPro) {

        //如果是禁用的不做验证直接 返回true
        if(this.$element.prop('disabled')){
            return true
        }

        var val = this.$element.val()


        if (val == null || val == undefined) val = ''

        if(val instanceof Array) return true

        val = val.replace(/^\s*|\s*$/g, "")

        if (!this.reg) return true


        for (var i = 0; i < this.reg.length; i++) {
            var obj = this.reg[i]

            var isOk = true

            if (obj.type == PtyxeleVerify.COM_NUM_TYPE) {

                isOk = this.compareNumber(obj.reg, val)

            } else if (obj.type == PtyxeleVerify.COM_CHAR_TYPE) {

                isOk = this.compareCharLength(obj.reg, val)

            } else if (obj.type == PtyxeleVerify.COM_OBJ_TYPE) {

                isOk = this.compareObject(obj.reg, val)

            } else if (obj.type == PtyxeleVerify.COM_DATE_TYPE) {

                isOk = this.compareDate(obj.reg, val)

            } else if (obj.type == PtyxeleVerify.COMMOM_TYPE) {

                var verifyObj = PtyxeleVerify.VERIFY[obj.reg]

                if (typeof  verifyObj.reg == 'function') {

                    isOk = verifyObj.reg(val)

                } else {

                    if (val == '') {
                        isOk = true
                    } else {
                        isOk = verifyObj.reg.test(val)
                    }
                }

            }

            if (!isOk && (isPro == null || isPro == undefined || isPro == true)) {
                this.alert(obj.msg)
            }

            if (!isOk) {
                return false
            }

        }

        return true
    }

    //比较数值
    PtyxeleVerify.prototype.compareNumber = function (reg, value) {

        if (!value) return true

        if (isNaN(value)) return false

        reg = reg.replace('!', '!=')

        if (reg.indexOf('=') == 0) {
            reg = reg.replace('=', '==');
        }
        return eval(value + reg)
    }


    //比较字符串长度
    PtyxeleVerify.prototype.compareCharLength = function (reg, value) {

        if (!value) return true

        reg = reg.replace('!', '!=')

        return eval(value.length + reg)
    }

    //比较对象
    PtyxeleVerify.prototype.compareObject = function (reg, value) {
        // value = value.replace(/^\s*|\s*$/g, "")

        if (!value) return true

        var operator = reg.substring(0, 1)

        var obj = reg.substring(1)

        operator = operator.replace('!', '!=')

        var $obj = $('#' + obj)

        if ($obj.length != 1) {
            alert('比较对象不存在或者存在对个对象')
            throw  new Error('比较对象不存在或者存在对个对象')
            return false
        }

        if (!$obj.ptyxeleEleVerify()) return false

        if (operator == '=') {
            operator = '=='
        }
        return eval('\'' + value + '\'' + operator + '\'' + $obj.val() + '\'')
    }

    //比较日期
    PtyxeleVerify.prototype.compareDate = function (reg, value) {

        if (!value) return true

        var operator = reg.substring(0, 1)

        operator = operator.replace('!', '!=')

        var strDate = reg.substring(1)

        var otherTime = new Date(strDate).getTime()

        var time = new Date(value).getTime()

        return eval(time + operator + otherTime)
    }

    //提示信息
    PtyxeleVerify.prototype.alert = function (msg) {

        layer.msg(msg, {
            offset: 'c',
            anim: 6
        })

        //定位
        var display = this.$element.css('display')

        if (display == 'none') {
            this.$element.css('display', 'block')[0].scrollIntoView()
            this.$element.css('display', 'none')
        }

        this.$element[0].focus()

        var node = this.$element[0].tagName

        var shakeType = 3

        if (node == 'INPUT' && $.inArray(this.$element.attr('type'), ['radio', 'checkbox']) != -1) {
            shakeType = 1
        }

        if (node == 'INPUT' && ($.inArray(this.$element.attr('type'), ['file']) != -1 || this.$element.attr('ptyx-load') != null)) {
            shakeType = 2
        }

        if (node == 'SELECT') {
            shakeType = 1
        }

        var $target = null

        if (shakeType == 1) {
            $target = this.$element.nextAll().filter(function (index) {
                return $(this).hasClass('layui-unselect') ? $(this) : null
            })
        } else if (shakeType == 2) {
            var $loadNode = this.$element.next('.ptcs-load')

            if ($loadNode.length == 0) return

            $target = $loadNode.find('.layui_upload')
        } else {
            $target = this.$element
        }

        this.shake($target)

    }

    //抖动
    PtyxeleVerify.prototype.shake = function (target) {
        var jqNode = $(target)
        jqNode.css({position: 'relative'})
        jqNode.addClass('ptcs-shake-verify')
        setTimeout(function () {
            jqNode.removeClass('ptcs-shake-verify')
        }, 1000)
    }

    function Plugin() {
        var $this = $(this)

        var data = $this.data(PtyxeleVerify.PACE)

        if (!data) $this.data(PtyxeleVerify.PACE, (data = new PtyxeleVerify(this)))
    }


    function EleVerify(isPro) {
        var $this = $(this)

        var data = $this.data(PtyxeleVerify.PACE)

        if (!data) return true

        return data.verify(isPro)
    }

    function FormVerify() {

        var $this = $(this)

        if ($this[0].tagName != 'FORM') return


        var notSubmit = $this.data(PtyxeleVerify.SUBMIT_STAT)

        if (notSubmit) return

        $this.data(PtyxeleVerify.SUBMIT_STAT, true)

        var $eles = $this.find('input[name],select[name],textarea[name]')

        if ($eles.length == 0) return true

        for (var i = 0; i < $eles.length; i++) {
            var stat = $($eles[i]).ptyxeleEleVerify()
            if (!stat) {
                $this.data(PtyxeleVerify.SUBMIT_STAT, false)
                return stat
            }
        }
        $this.data(PtyxeleVerify.SUBMIT_STAT, false)
        return true

    }

    function Submit(e) {

        var $this = $(this)

        if ($this.ptyxeleFormVerify()) {
            oldSubmit.call($this)
        } else {
            // this.preventDefault();//此处阻止提交表单
            event.preventDefault()
            return false
        }

    }

    function PtyxSubmit(callback) {

        var $this = $(this)

        if ($this[0].tagName != 'FORM') return

        var action = $this.attr('action') ? $this.attr('action') : window.location.href

        var requestData = new Object()

        console.info($tis.serialize())
        console.info($tis.serializeArray())

        requestData["requestData"] = JSON.stringify($this.serialize())


        // $.ajx({
        //     url:
        // })
    }

    var oldSubmit = $.fn.submit

    $.fn.submit = Submit

    $.fn.ptyxSubmit = PtyxSubmit

    $.fn.ptyxeleEleVerify = EleVerify

    $.fn.ptyxeleVerify = Plugin

    $.fn.ptyxeleFormVerify = FormVerify

    $(window).on('load', function () {
        $('input[name],select[name],textarea[name]').each(function () {
            $(this).ptyxeleVerify()
        })


        $('form[ptyx-form]').on('submit', function () {
            $(this).submit()
        })
    })

}(jQuery);

/**
 * Created by chenzp on 18-4-4.
 */
+function ($) {

    var PtyxeleDict = function (ele, option) {
        this.$element = $(ele)
        this.options = $.extend({}, PtyxeleDict.DEFAULT, option)
        this.init()
    }

    PtyxeleDict.PACE = 'ptyxele-dict'

    PtyxeleDict.DEFAULT = {

        /**
         * 如果不填写则默认不存空值选择
         */
        // placeholder:'请选择'
        /**
         * 需要过滤字典，接收单个多个值
         */
        filter: []
        /**
         * 设置选中的字段
         */
        , cvalue: 'dictCode'
        /**
         * 设置显示字段
         */
        , cshow: 'dictName'
        /**
         * 字典库过滤的字段
         */
        , ctype: 'dictType'
    }

    //初始化
    PtyxeleDict.prototype.init = function () {

        this.mergeOption()

        var opt = this.options

        //判断是否存在请求地址
        if (!opt.url) throw  new Error('初始化字典组件请求地址不能为空')

        if (!opt.type) throw new Error('请指定要初始化字典库类型')

        var tagNode = this.$element[0].tagName

        if (tagNode == 'SELECT') {
            this.createSelect()
            this.loadData(false)
        } else {
            this.createNode()
        }

    }

    //创建select
    PtyxeleDict.prototype.createSelect = function () {
        var $node = this.$element
        var $this = this
        var opt = this.options

        this.$element.hide()

        var str = '  <div class="layui-unselect layui-form-select">' +
            '        <div class="layui-select-title">' +
            '            <input type="text"  class="layui-input layui-unselect" readonly/>' +
            '            <input type="hidden"/>' +
            '            <i class="layui-edge"></i>' +
            '        </div>' +
            '        <dl class="layui-anim layui-anim-upbit"></dl>' +
            '    </div>'

        var $str = $(str)


        $str.find('input').on('click', function () {
            var selchecked = 'layui-form-selected'

            var parent = '.layui-unselect.layui-form-select'

            if ($str.hasClass(selchecked)) {
                $(parent).removeClass(selchecked)
                $str.removeClass(selchecked)
            } else {
                $(parent).removeClass(selchecked)
                $str.addClass(selchecked)
            }
        })

        this.$element.after($str)

        this.$select = $str

        var $input = this.$input = $str.find('input')

        if (opt.placeholder) {
            $input.attr('placeholder', opt.placeholder)
        }
    }

    PtyxeleDict.prototype.createNode = function () {

        var $node = this.$element
        var $this = this
        var opt = this.options

        if (opt.placeholder) {
            $node.attr('placeholder', opt.placeholder).attr('title', opt.placeholder)
        }
    }


    //请求数据
    PtyxeleDict.prototype.loadData = function (isSync) {

        var $this = this
        var opt = $this.options

        var reqData = new Object()
        reqData[opt.ctype] = opt.type

        $.ajax({
            url: opt.url
            , dataType: 'json'
            , data: reqData
            , async: isSync ? false : true
            , success: function (res) {

                if (!res.successful) {
                    if (res.msg) {
                        throw new Error(res.msg)
                    }
                    throw new Error('数据请求失败')
                } else {
                    if (res.result) {
                        $this.drawData(res.result)
                        $this.store = res.result
                    }
                }
            }
            , error: function (e) {
                throw (e)
            }
        })
    }

    //请求数据
    PtyxeleDict.prototype.loadData1 = function (isSync) {

        var $this = this
        var opt = $this.options

        var reqData = new Object()
        reqData[opt.ctype] = opt.type

        $.ajax({
            url: opt.url
            , dataType: 'json'
            , data: reqData
            , async: isSync ? false : true
            , success: function (res) {

                if (!res.successful) {
                    if (res.msg) {
                        throw new Error(res.msg)
                    }
                    throw new Error('数据请求失败')
                } else {
                    if (res.result) {
                        $this.store = res.result
                    }
                }
            }
            , error: function (e) {
                throw (e)
            }
        })
    }

    //渲染数据
    PtyxeleDict.prototype.drawData = function (data) {

        var opt = this.options

        if (!data) throw new Error('数据不能空')


        if (opt.filter) {

            var filterArr = new Array()
            if (typeof opt.filter == 'string' || typeof  opt.filter == 'number') {
                filterArr.push(opt.filter + '')
            } else if (opt.filter instanceof Array) {
                filterArr = filterArr.concat(opt.filter)
            }

            for (var i = 0; i < data.length; i++) {

                for (var j = 0; j < filterArr.length; j++) {
                    if (data[i] && data[i][opt.cvalue] == filterArr[j] + '') {
                        delete  data[i]
                    }
                }
            }
        }


        if (opt.placeholder) {
            this.$select.find('dl').append('<dd lay-value="" class="layui-select-tips">' + opt.placeholder + '</dd>')
        }


        for (var i = 0; i < data.length; i++) {

            if (!data[i]) continue

            var $dd = $('<dd></dd>').attr('lay-value', data[i][opt.cvalue]).html(data[i][opt.cshow])

            this.$select.find('dl').append($dd)

            var $this = this

            if (i == 0 && !opt.placeholder) {
                $this.$input.val(data[i][opt.cshow])
                $dd.trigger('click')
            }
        }


        this.$select.find('dd').on('click', function () {
            $this.$select.find('dd.layui-this').removeClass('layui-this')


            var oldVal = $this.value
            var isChange = false
            if ($(this).hasClass('layui-select-tips')) {
                $this.value = ''
                $this.$input.val('')
                if(oldVal){
                    isChange = true
                }
            } else {
                $this.value = $(this).addClass('layui-this').attr('lay-value')
                $this.$input.val($(this).html())

                if($this.value != oldVal){
                    isChange = true
                }
            }
            $this.$select.removeClass('layui-form-selected')

            $this.$element.find('option').remove()
            var $option = $('<option value="' + $this.value + '"></option>').prop('selected', true)
            $this.$element.append($option)

            $this.$element.trigger('click')
            if(isChange){
                $this.$element.trigger('change')
            }


        })
    }


    //获取下拉框值
    PtyxeleDict.prototype.val = function (value) {
        if (value == undefined || value == null) {
            return this.value ? this.value:''
        }


        if (this.$select) {
            if (!this.store) this.loadData(true)
            this.$select.find('dd[lay-value="' + value + '"]').trigger('click')
        } else {
            if (!this.store) this.loadData1(true)
            var opt = this.options
            for (var i = 0; i < this.store.length; i++) {
                var obj = this.store[i]
                if (obj[[opt.cvalue]] == value) {
                    if (this.$element[0].tagName == 'INPUT') {
                        this.$element.attr('value', obj[opt.cshow])
                    } else {
                        this.$element.text(obj[opt.cshow])
                    }

                    break
                }
            }
        }

        return this.$element
    }


    function Plugin(options) {
        return this.each(function () {
            var $this = $(this)
            var data = $this.data(PtyxeleDict.PACE)

            Ptyxele()

            if (!data) {

                var dd = $.extend(true, PtyxeleDict.prototype, Ptyxele.prototype, PtyxeleDict.prototype)

                $this.data(PtyxeleDict.PACE, (data = new dd.constructor(this, options)))
            }
        })
    }


    function SelectValue(value) {

        var $this = $(this)

        var data = $this.data(Ptyxele.PTYXELE)

        var dictData = $this.data(PtyxeleDict.PACE)

        if (!data || !dictData) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }

        return dictData.val(value)
    }

    var oldVal = $.fn.val

    $.fn.ptyxeleDict = Plugin
    $.fn.val = SelectValue

    $(window).on('load', function () {
        $('[ptyx-dict],[ptyx-data*="module:dict"]').each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxeleDict()
        })
    })

    $(document).on(' create.dict.ptyxele-api', '[ptyx-dict],[ptyx-data*="module:dict"]', function () {
        $(this).parsePtyxeleResolver()
        $(this).ptyxeleDict()
    })

}(jQuery);


/**
 * Created by chenzp on 18-4-13.
 */
+function ($) {

    var PtyxeleUedit = function (ele, option) {
        this.$element = $(ele)
        this.options = $.extend({}, PtyxeleUedit.DEFAULT, option)
        this.init()
    }

    PtyxeleUedit.PACE = 'ptyxele-uedit'

    PtyxeleUedit.DEFAULT = {}

    //初始化
    PtyxeleUedit.prototype.init = function () {

        this.mergeOption()

        var opt = this.options

        var $textarea = $('<textarea></textarea>')
        var id = Ptyxele.UTIL.uuid(50, 50)

        $textarea.attr('id', id)
        this.$element.hide()

        this.$element.after($textarea)

        this.id = id

        UE.getEditor(id, {
            autoFloatEnabled: false
        })
    }


    //获取下拉框值
    PtyxeleUedit.prototype.val = function (value) {
        if (value + '' == 'undefined') {

            var editor = UE.getEditor(this.id)
            if (editor) {
                return editor.getContent()
            }
        } else {

            if (value == null) return this.$element


            var editor = UE.getEditor(this.id)

            if (editor) {

                var i = 0

                var timer = setInterval(function () {

                    if (i == 50) {
                        clearInterval(timer)
                        return
                    }

                    if (editor.body) {
                        editor.setContent(value)
                        clearInterval(timer)
                        return
                    }

                    i++

                }, 200)
            }
            return this.$element
        }
    }


    function Plugin(options) {
        return this.each(function () {

            // var uuid = Ptyxele.UTIL.uuid(50,50)

            var $this = $(this)
            var data = $this.data(PtyxeleUedit.PACE)

            Ptyxele()

            if (!data) {

                var dd = $.extend(true, PtyxeleUedit.prototype, Ptyxele.prototype, PtyxeleUedit.prototype)

                $this.data(PtyxeleUedit.PACE, (data = new dd.constructor(this, options)))
            }
        })
    }


    function SelectValue(value) {

        var $this = $(this)

        var data = $this.data(Ptyxele.PTYXELE)

        var editorData = $this.data(PtyxeleUedit.PACE)

        if (!data || !editorData) {
            return value == null || value == undefined ? oldVal.call($this) : oldVal.call($this, value)
        }

        return editorData.val(value)
    }

    var oldVal = $.fn.val

    $.fn.ptyxeleUedite = Plugin

    $.fn.val = SelectValue

    $(window).on('load', function () {
        $('[ptyx-uedit],[ptyx-data*="module:uedit"]').each(function () {
            $(this).parsePtyxeleResolver()
            $(this).ptyxeleUedite()
        })
    })

    $(document).on(' create.uedit.ptyxele-api', '[ptyx-uedit],[ptyx-data*="module:uedit"]', function () {
        $(this).ptyxeleUedite()
    })

}(jQuery);







